source: trunk/Lucide/gui/lucide.cpp @ 397

Last change on this file since 397 was 397, checked in by dmik, 11 years ago

Fixed restoring the fullscreen state when the normal size equals to the fullscreen size.

File size: 55.6 KB
Line 
1/* ***** BEGIN47 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_SPL
36#define INCL_SPLDOSPRINT
37#include "os2all.h"
38
39#include <string>
40#include <set>
41#include <stdio.h>
42#include <stdlib.h>
43#include <process.h>
44#if defined(__WATCOM__)
45#include <dos.h>
46#define find_t_name(find_t) find_t.name
47#else
48#include <unistd.h>
49#include <emx/syscalls.h>
50typedef _find find_t;
51#define find_t_name(find_t) find_t.szName
52#define _dos_findfirst __findfirst
53#define _dos_findnext __findnext
54#define _dos_findclose(a) do {} while(0)
55#endif
56
57#include <ludoc.xh>
58
59#include "Lucide.h"
60#include "pluginman.h"
61#include "pluginViewDlg.h"
62#include "fontsInfoDlg.h"
63#include "docInfoDlg.h"
64#include "findDlg.h"
65#include "printDlg.h"
66#include "progressDlg.h"
67#include "settingsDlg.h"
68#include "passwordDlg.h"
69#include "docViewer.h"
70#include "indexWindow.h"
71#include "recent.h"
72#include "lusettings.h"
73#include "luutils.h"
74#include "tb_spl.h"
75#include "Lucide_res.h"
76#include "messages.h"
77
78
79#define ID_SPLITTER 1
80
81const char *appName    = "Lucide";
82const char *appVersion = VERSION;
83const char *appDate = VERSIONDATE;
84const char *prfFwp     = "FrameWindowPos";
85const char *prfLvd     = "LastViewedDir";
86const char *prfSplpos  = "SplitterPos";
87const char *prfShowind = "ShowIndex";
88const char *prfMaxView = "MaxView";
89const char *prfFs      = "FullScreen";
90
91HWND createToolbar( HWND hwnd );
92void AboutBox( HWND hWndFrame );
93void initPipeMon( HWND hWndFrame );
94void unInitPipeMon();
95HWND LcdFileDlg( HWND hwndP, HWND hwndO, FILEDLG *pfild );
96
97
98HAB   hab            = NULLHANDLE;
99HWND  hWndFrame      = NULLHANDLE;
100HWND  hWndMenu       = NULLHANDLE;
101HWND  hToolBar       = NULLHANDLE;
102HWND  hVertSplitter  = NULLHANDLE;
103HWND  hHorizSplitter = NULLHANDLE;
104HWND  hFrameSysmenu  = NULLHANDLE;
105HWND  hFrameTitlebar = NULLHANDLE;
106HWND  hFrameMinMax   = NULLHANDLE;
107
108Environment    *ev        = somGetGlobalEnvironment();
109LuDocument     *doc       = NULL;
110PluginManager  *pluginMan = NULL;
111DocumentViewer *docViewer = NULL;
112IndexWindow    *indexWin  = NULL;
113FindDlg        *findDlg   = NULL;
114LuSettings     *settings  = NULL;
115RecentFiles    *recent    = NULL;
116char           *title     = NULL;
117
118
119bool         Lucide::dontSwitchPage                = false;
120SHORT        Lucide::splitterPos                   = 100;
121bool         Lucide::showIndex                     = true;
122bool         Lucide::isMaxview                     = false;
123bool         Lucide::isFullscreen                  = false;
124LuWindowPos  Lucide::winPos                        = {0};
125char         Lucide::docFullName[ CCHMAXPATH ]     = "";
126char         Lucide::docFileName[ CCHMAXPATHCOMP ] = "";
127char         Lucide::docDirName[ CCHMAXPATHCOMP ]  = "";
128char        *Lucide::password                      = NULL;
129ActiveWindow Lucide::activeWindow                  = AwView;
130// static data for asynch loading document
131ProgressDlg *Lucide::loadProgressDlg               = NULL;
132bool         Lucide::docLoaded                     = false;;
133char        *Lucide::loadError                     = NULL;
134long         Lucide::loadErrorCode                 = LU_LDERR_NO_ERROR;
135char        *Lucide::thumbnailData                 = NULL;
136int          Lucide::thumbnailDataLen              = 0;
137
138// List of files in current directory
139static std::set<std::string> fileList;
140static std::set<std::string>::const_iterator fileListIterator;
141
142HMODULE _hmod = NULLHANDLE;
143
144unsigned APIENTRY LibMain( unsigned hmod, unsigned termination )
145{
146    if ( termination ) {
147        // DLL is detaching from process
148    } else {
149        // DLL is attaching to process
150        _hmod = hmod;
151    }
152    return( 1 );
153}
154
155#if !defined(__WATCOM__)
156extern "C" unsigned long _System _DLL_InitTerm( unsigned long mod_handle,
157                                                unsigned long flag )
158{
159    int _CRT_init();
160    void _CRT_term();
161    void __ctordtorInit();
162    void __ctordtorTerm();
163
164    switch ( flag ) {
165        case 0:
166            if ( _CRT_init() != 0 )
167                return 0;
168            __ctordtorInit();
169            return LibMain( mod_handle, flag );
170        case 1:
171            __ctordtorTerm();
172            _CRT_term ();
173            return LibMain( mod_handle, flag );
174        default:
175            return 0;
176    }
177}
178#endif
179
180
181// stolen from xWorkplace sources
182static
183APIRET my_DosQueryProcAddr(PCSZ pcszModuleName, ULONG ulOrdinal, PFN *ppfn)
184{
185    HMODULE hmod = NULL;
186    APIRET rc = 0;
187    if (!(rc = DosQueryModuleHandle( (PSZ)pcszModuleName, &hmod))) {
188        if ((rc = DosQueryProcAddr( hmod, ulOrdinal, NULL, ppfn))) {
189            // the CP programming guide and reference says use
190            // DosLoadModule if DosQueryProcAddr fails with this error
191            if (rc == ERROR_INVALID_HANDLE) {
192                if (!(rc = DosLoadModule(NULL, 0, (PSZ) pcszModuleName,
193                                         &hmod))) {
194                    rc = DosQueryProcAddr(hmod, ulOrdinal, NULL, ppfn);
195                }
196            }
197        }
198    }
199    return rc;
200}
201
202
203PFNWP pOldFrameProc = NULL;
204PFNWP pOldSplProc   = NULL;
205
206void Lucide::enableCopy( bool enable )
207{
208    WinEnableMenuItem( hWndMenu, CM_COPY, enable );
209}
210
211void Lucide::setOfPages( long pages )
212{
213    char *pgfrm = newstrdupL( TB_PAGENUM );
214    char pgnum[ 32 ];
215    snprintf( pgnum, sizeof( pgnum ), pgfrm, pages );
216    delete pgfrm;
217    WinSetDlgItemText( hToolBar, TBID_OFPAGES, pgnum );
218    WinSendDlgItemMsg( hToolBar, TBID_PAGENUM, SPBM_SETLIMITS,
219                       MPFROMLONG( pages ), MPFROMLONG( 1 ) );
220}
221
222void Lucide::checkNavigationMenus()
223{
224    WinEnableMenuItem( hWndMenu, CM_GOTOPAGE, TRUE );
225    BOOL enfirst = ( docViewer->getCurrentPage() != 0 );
226    BOOL enlast = ( docViewer->getCurrentPage() != ( doc->getPageCount( ev ) - 1 ) );
227    WinEnableMenuItem( hWndMenu, CM_FIRSTPAGE, enfirst );
228    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FIRSTPAGE), (MPARAM)enfirst );
229    WinEnableMenuItem( hWndMenu, CM_PREVPAGE, enfirst );
230    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_PREVPAGE), (MPARAM)enfirst );
231    WinEnableMenuItem( hWndMenu, CM_NEXTPAGE, enlast );
232    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_NEXTPAGE), (MPARAM)enlast );
233    WinEnableMenuItem( hWndMenu, CM_LASTPAGE, enlast );
234    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_LASTPAGE), (MPARAM)enlast );
235
236    bool tmp = dontSwitchPage;
237    dontSwitchPage = true;
238    WinSendDlgItemMsg( hToolBar, TBID_PAGENUM, SPBM_SETCURRENTVALUE,
239                       MPFROMLONG( docViewer->getCurrentPage() + 1 ), MPVOID );
240    dontSwitchPage = tmp;
241    indexWin->goToPage( NULL, docViewer->getCurrentPage() );
242}
243
244void Lucide::enableZoomMenus()
245{
246    BOOL scalable = doc->isScalable( ev );
247    WinEnableMenuItem( hWndMenu, CM_FITWINDOW, scalable );
248    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FITWINDOW), (MPARAM)scalable );
249    WinEnableMenuItem( hWndMenu, CM_ACTSIZE, scalable );
250    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_ACTSIZE), (MPARAM)scalable );
251    WinEnableMenuItem( hWndMenu, CM_FITWIDTH, scalable );
252    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FITWIDTH), (MPARAM)scalable );
253    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_ZOOM_IN_OUT), (MPARAM)scalable );
254    WinEnableMenuItem( hWndMenu, CM_ZOOM_IN, scalable );
255    WinEnableMenuItem( hWndMenu, CM_ZOOM_OUT, scalable );
256    WinEnableControl( hToolBar, TBID_ZOOM, scalable );
257    BOOL rotable = doc->isRotable( ev );
258    WinEnableMenuItem( hWndMenu, CM_ROTATE90CW, rotable );
259    WinEnableMenuItem( hWndMenu, CM_ROTATE90CCW, rotable );
260}
261
262
263void Lucide::setZoomChecks( SHORT cmd, SHORT cbind, double zoom )
264{
265    if ( cmd != -1 )
266    {
267        WinCheckMenuItem( hWndMenu, cmd, TRUE );
268        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( cmd ), (MPARAM)TRUE );
269    }
270
271    if ( cbind != -1 )
272    {
273        char buf[ 255 ] = "";
274        WinSendDlgItemMsg( hToolBar, TBID_ZOOM, LM_QUERYITEMTEXT,
275                           MPFROM2SHORT( cbind, sizeof( buf ) ), MPFROMP( buf ) );
276        WinSetDlgItemText( hToolBar, TBID_ZOOM, buf );
277    }
278
279    if ( zoom != 0 )
280    {
281        std::string z = str( zoom * 100.0 ) + "%";
282        WinSetDlgItemText( hToolBar, TBID_ZOOM, z.c_str() );
283    }
284}
285
286void Lucide::checkZoomMenus()
287{
288    double zoom = docViewer->getZoom();
289
290    WinCheckMenuItem( hWndMenu, CM_FITWINDOW, FALSE );
291    WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT(CM_FITWINDOW), (MPARAM)FALSE );
292    WinCheckMenuItem( hWndMenu, CM_ACTSIZE, FALSE );
293    WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT(CM_ACTSIZE), (MPARAM)FALSE );
294    WinCheckMenuItem( hWndMenu, CM_FITWIDTH, FALSE );
295    WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT(CM_FITWIDTH), (MPARAM)FALSE );
296
297    if ( zoom == -2 ) {
298        setZoomChecks( CM_FITWINDOW, 1, 0 );
299    } else if ( zoom == -1 ) {
300        setZoomChecks( CM_FITWIDTH, 2, 0 );
301    } else if ( zoom == 1 ) {
302        setZoomChecks( CM_ACTSIZE, 0, 0 );
303    } else {
304        setZoomChecks( -1, -1, zoom );
305    }
306}
307
308void Lucide::checkMenus( bool initial )
309{
310    if ( initial )
311    {
312        // pre-set "Actual size"
313        setZoomChecks( CM_ACTSIZE, 0, 0 );
314    }
315
316    if ( doc == NULL )
317    {
318        if ( initial )
319        {
320            // "single page" mode by default
321            WinCheckMenuItem( hWndMenu, CM_SINGLEPAGE, TRUE );
322        }
323
324        WinEnableMenuItem( hWndMenu, CM_SAVEAS, FALSE );
325        WinEnableMenuItem( hWndMenu, CM_CLOSE, FALSE );
326        WinEnableMenuItem( hWndMenu, CM_PRINT, FALSE );
327        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_PRINT), (MPARAM)FALSE );
328        WinEnableMenuItem( hWndMenu, CM_DOCINFO, FALSE );
329        WinEnableMenuItem( hWndMenu, CM_FONTSINFO, FALSE );
330
331        WinEnableMenuItem( hWndMenu, CM_COPY, FALSE );
332        WinEnableMenuItem( hWndMenu, CM_SELECTALL, FALSE );
333        WinEnableMenuItem( hWndMenu, CM_FIND, FALSE );
334        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FIND), (MPARAM)FALSE );
335        WinEnableMenuItem( hWndMenu, CM_FINDAGAIN, FALSE );
336        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FINDAGAIN), (MPARAM)FALSE );
337
338        WinEnableMenuItem( hWndMenu, CM_FIRSTPAGE, FALSE );
339        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FIRSTPAGE), (MPARAM)FALSE );
340        WinEnableMenuItem( hWndMenu, CM_PREVPAGE, FALSE );
341        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_PREVPAGE), (MPARAM)FALSE );
342        WinEnableMenuItem( hWndMenu, CM_NEXTPAGE, FALSE );
343        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_NEXTPAGE), (MPARAM)FALSE );
344        WinEnableMenuItem( hWndMenu, CM_LASTPAGE, FALSE );
345        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_LASTPAGE), (MPARAM)FALSE );
346        WinEnableMenuItem( hWndMenu, CM_GOTOPAGE, FALSE );
347
348        WinEnableMenuItem( hWndMenu, CM_FITWINDOW, FALSE );
349        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FITWINDOW), (MPARAM)FALSE );
350        WinEnableMenuItem( hWndMenu, CM_ACTSIZE, FALSE );
351        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_ACTSIZE), (MPARAM)FALSE );
352        WinEnableMenuItem( hWndMenu, CM_FITWIDTH, FALSE );
353        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FITWIDTH), (MPARAM)FALSE );
354        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_ZOOM_IN_OUT), (MPARAM)FALSE );
355        WinEnableMenuItem( hWndMenu, CM_ZOOM_IN, FALSE );
356        WinEnableMenuItem( hWndMenu, CM_ZOOM_OUT, FALSE );
357        WinEnableControl( hToolBar, TBID_ZOOM, FALSE );
358
359        WinEnableMenuItem( hWndMenu, CM_ROTATE90CW, FALSE );
360        WinEnableMenuItem( hWndMenu, CM_ROTATE90CCW, FALSE );
361        WinEnableMenuItem( hWndMenu, CM_SINGLEPAGE, FALSE );
362        WinEnableMenuItem( hWndMenu, CM_CONTINUOUS, FALSE );
363
364        setOfPages( 0 );
365        return;
366    }
367
368
369    checkNavigationMenus();
370    enableZoomMenus();
371    checkZoomMenus();
372
373    WinEnableMenuItem( hWndMenu, CM_PRINT, TRUE );
374    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_PRINT), (MPARAM)TRUE );
375    WinEnableMenuItem( hWndMenu, CM_SAVEAS, doc->isSaveable( ev ) );
376    WinEnableMenuItem( hWndMenu, CM_CLOSE, TRUE );
377    setOfPages( doc->getPageCount( ev ) );
378    WinEnableMenuItem( hWndMenu, CM_FONTSINFO, doc->isHaveFontInfo( ev ) );
379    WinEnableMenuItem( hWndMenu, CM_DOCINFO, TRUE );
380
381    BOOL haveText = doc->isHaveText( ev );
382    WinEnableMenuItem( hWndMenu, CM_FIND, haveText );
383    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FIND), (MPARAM)haveText );
384    WinEnableMenuItem( hWndMenu, CM_SELECTALL, haveText );
385
386    WinEnableMenuItem( hWndMenu, CM_SINGLEPAGE, TRUE );
387    WinEnableMenuItem( hWndMenu, CM_CONTINUOUS, TRUE );
388}
389
390void Lucide::goToPage( long page )
391{
392    if ( docViewer != NULL ) {
393        docViewer->goToPage( page );
394    }
395}
396
397void Lucide::setZoom( double zoom )
398{
399    if ( docViewer != NULL ) {
400        docViewer->setZoom( zoom );
401        checkZoomMenus();
402    }
403}
404
405void Lucide::setDocument( LuDocument *_doc )
406{
407    docViewer->setDocument( _doc );
408    indexWin->setDocument( _doc );
409    checkMenus( false );
410}
411
412void Lucide::setPageLayout( PgLayout layout )
413{
414    if ( layout == SinglePage ) {
415        WinCheckMenuItem( hWndMenu, CM_SINGLEPAGE, TRUE );
416        WinCheckMenuItem( hWndMenu, CM_CONTINUOUS, FALSE );
417    }
418    else {
419        WinCheckMenuItem( hWndMenu, CM_SINGLEPAGE, FALSE );
420        WinCheckMenuItem( hWndMenu, CM_CONTINUOUS, TRUE );
421    }
422
423    docViewer->setPageLayout( layout );
424}
425
426
427bool Lucide::closeDocument( bool force )
428{
429    if ( doc != NULL ) {
430        if ( !docViewer->close( force ) && !force )
431            return false;
432        delete doc;
433        doc = NULL;
434        WinSetWindowText( hWndFrame, title );
435        checkMenus( false );
436    }
437
438    if ( thumbnailData != NULL ) {
439        writeThumbnail( docFullName );
440        delete thumbnailData;
441        thumbnailData = NULL;
442        thumbnailDataLen = 0;
443    }
444
445    return true;
446}
447
448void Lucide::loadthread( void* )
449{
450    HAB thab = WinInitialize( 0 );
451    HMQ thmq = WinCreateMsgQueue( thab, 0 );
452
453    docLoaded = doc->loadFile( ev, docFullName, password, &loadErrorCode, &loadError );
454    if ( docLoaded ) {
455        if ( doc->isCreateFileThumbnail( ev ) && isThumbNeeded( docFullName ) ) {
456            loadProgressDlg->setText( getLocalizedString( MSGS_CREATING_THUMBNAIL ).c_str() );
457            createThumbnail( doc );
458        }
459    }
460    loadProgressDlg->hide();
461
462    WinDestroyMsgQueue( thmq );
463    WinTerminate( thab );
464    _endthread();
465}
466
467void Lucide::loadDocument( const char *fn )
468{
469    // test if file supported and then close previous opened document
470    if ( pluginMan->createDocumentForFile( fn, true ) == NULL )
471    {
472        char *msg = newstrdupL( MSGS_NO_SUIT_PLUG );
473        WinMessageBox( HWND_DESKTOP, hWndFrame, msg,
474                       NULL, 0, MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE );
475        delete msg;
476    }
477    else
478    {
479        if ( !closeDocument() )
480            return;
481
482        doc = pluginMan->createDocumentForFile( fn, false );
483        if ( doc == NULL )
484        {
485            char *msg = newstrdupL( MSGS_NO_SUIT_PLUG );
486            WinMessageBox( HWND_DESKTOP, hWndFrame, msg,
487                           NULL, 0, MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE );
488            delete msg;
489        }
490        else
491        {
492            _fullpath( docFullName, fn, CCHMAXPATH );
493
494            if ( password != NULL ) {
495                delete password;
496                password = NULL;
497            }
498            bool once = true;
499            while ( once || ( password != NULL ) )
500            {
501                once = false;
502                docLoaded = false;
503                loadError = NULL;
504
505                // Load document asynchronously
506                loadProgressDlg = new ProgressDlg( hWndFrame );
507                char *ldmsg = newstrdupL( MSGS_LOADING_DOCUMENT );
508                loadProgressDlg->setText( ldmsg );
509                delete ldmsg;
510                loadProgressDlg->show( loadthread, NULL ); // doc will be loaded
511                delete loadProgressDlg;
512
513                if ( password != NULL ) {
514                    delete password;
515                    password = NULL;
516                }
517
518                if ( docLoaded )
519                {
520                    char *t = new char[ 2048 ];
521                    char _dr[ _MAX_DRIVE ];
522                    char _di[ _MAX_DIR ];
523                    char _fn[ _MAX_FNAME ];
524                    char _ex[ _MAX_EXT ];
525                    _splitpath( docFullName, _dr, _di, _fn, _ex );
526                    strcpy( docDirName, _dr );
527                    strcat( docDirName, _di );
528                    strcpy( docFileName, _fn );
529                    strcat( docFileName, _ex );
530                    snprintf( t, 2048, "%s - %s", docFileName, title );
531                    WinSetWindowText( hWndFrame, t );
532                    delete t;
533                    recent->addFile( docFullName );
534                    setDocument( doc );
535                }
536                else
537                {
538                    if ( loadErrorCode == LU_LDERR_NO_ERROR )
539                    {
540                        char *m = newstrdupL( MSGS_FILE_LOAD_ERROR );
541                        WinMessageBox( HWND_DESKTOP, hWndFrame, m,
542                                       NULL, 0, MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE );
543                        delete m;
544                    }
545                    else
546                    {
547                        std::string msgTempl = getLocalizedString( MSGS_LDERR );
548
549                        const int errmsgLen = 1024;
550                        char *errmsg = new char[ errmsgLen ];
551                        memset( errmsg, 0, errmsgLen );
552
553                        if ( loadErrorCode == LU_LDERR_CUSTOM )
554                        {
555                            snprintf( errmsg, errmsgLen, msgTempl.c_str(), loadError );
556                            SOMFree( loadError );
557                        }
558                        else
559                        {
560                            const char *lmsg = NULL;
561                            switch ( loadErrorCode )
562                            {
563                                case LU_LDERR_OUT_OF_MEMORY:
564                                    lmsg = MSGS_LDERR_OUT_OF_MEMORY;
565                                    break;
566                                case LU_LDERR_OPEN_ERROR:
567                                    lmsg = MSGS_LDERR_OPEN_ERROR;
568                                    break;
569                                case LU_LDERR_READ_ERROR:
570                                    lmsg = MSGS_LDERR_READ_ERROR;
571                                    break;
572                                case LU_LDERR_DAMAGED:
573                                    lmsg = MSGS_LDERR_DAMAGED;
574                                    break;
575                                case LU_LDERR_WRONG_FORMAT:
576                                    lmsg = MSGS_LDERR_WRONG_FORMAT;
577                                    break;
578                                case LU_LDERR_ENCRYPTED:
579                                    {
580                                        lmsg = MSGS_LDERR_ENCRYPTED;
581
582                                        PasswordDlg *pd = new PasswordDlg( hWndFrame );
583                                        if ( pd->showDialog() == DID_OK ) {
584                                            password = newstrdup( pd->getPassword() );
585                                        }
586                                        delete pd;
587                                    }
588                                    break;
589                            }
590
591                            if ( lmsg != NULL ) {
592                                snprintf( errmsg, errmsgLen, msgTempl.c_str(),
593                                          getLocalizedString( lmsg ).c_str() );
594                            }
595                        }
596
597                        if ( password == NULL )
598                        {
599                            WinMessageBox( HWND_DESKTOP, hWndFrame, errmsg, NULL, 0,
600                                           MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE );
601                        }
602                        delete errmsg;
603                    } // ( loadErrorCode == LU_LDERR_NO_ERROR )
604
605                    if ( password == NULL ) {
606                        delete doc;
607                        doc = NULL;
608                    }
609                } // ( docLoaded )
610            } // while ( once || ( password != NULL ) )
611        } // ( doc == NULL )
612    } // ( pluginMan->createDocumentForFile( fn, true ) == NULL )
613
614    loadFileList();
615}
616
617void Lucide::readMask( const char *mask )
618{
619    char *buf = new char[ CCHMAXPATH ];
620    strcpy( buf, docFullName );
621    char *r = strrchr( buf, '\\' );
622    if ( r != NULL )
623    {
624        *( r + 1 ) = 0;
625        strcat( buf, mask );
626
627        find_t ffblk;
628        unsigned done = _dos_findfirst( buf, _A_RDONLY | _A_NORMAL, &ffblk );
629        while ( done == 0 )
630        {
631            fileList.insert( find_t_name( ffblk ) );
632            done = _dos_findnext( &ffblk );
633        }
634        _dos_findclose( &ffblk );
635
636    }
637    delete buf;
638}
639
640void Lucide::loadFileList()
641{
642    fileList.clear();
643
644    char *exts = newstrdup( pluginMan->getExtsMask().c_str() );
645
646    char *p = strtok( exts, ";" );
647    while ( p != NULL )
648    {
649        readMask( p );
650        p = strtok( NULL, ";" );
651    }
652    delete exts;
653
654    fileListIterator = fileList.find( docFileName );
655}
656
657void Lucide::openDocument()
658{
659    PFILEDLG fd = new FILEDLG;
660    memset( fd, 0, sizeof( FILEDLG ) );
661    fd->cbSize = sizeof( FILEDLG );
662    fd->fl = FDS_CENTER | FDS_OPEN_DIALOG;
663    PrfQueryProfileString( HINI_USERPROFILE, appName, prfLvd, "",
664                           fd->szFullFile, sizeof( fd->szFullFile ) );
665    LcdFileDlg( HWND_DESKTOP, hWndFrame, fd );
666    if ( fd->lReturn == DID_OK )
667    {
668        char drv[ _MAX_DRIVE ] = "";
669        char dir[ _MAX_PATH ] = "";
670        char buf[ _MAX_PATH ] = "";
671        _splitpath( fd->szFullFile, drv, dir, NULL, NULL );
672        _makepath( buf, drv, dir, NULL, NULL );
673        PrfWriteProfileString( HINI_USERPROFILE, appName, prfLvd, buf );
674
675        loadDocument( fd->szFullFile );
676    }
677    delete fd;
678}
679
680bool Lucide::saveDocumentAs()
681{
682    bool saved = false;
683
684    char dirbuf[ CCHMAXPATH ];
685    PFILEDLG fd = new FILEDLG;
686    memset( fd, 0, sizeof( FILEDLG ) );
687    fd->cbSize = sizeof( FILEDLG );
688    fd->fl = FDS_CENTER | FDS_SAVEAS_DIALOG;
689    PrfQueryProfileString( HINI_USERPROFILE, appName, prfLvd, "",
690                           dirbuf, sizeof( dirbuf ) );
691    char fil[ _MAX_FNAME ] = "";
692    char ext[ _MAX_EXT ] = "";
693    _splitpath( docFullName, NULL, NULL, fil, ext );
694    snprintf( fd->szFullFile, sizeof( fd->szFullFile ),
695                "%s%s%s", dirbuf, fil, ext );
696    WinFileDlg( HWND_DESKTOP, hWndFrame, fd );
697    if ( fd->lReturn == DID_OK )
698    {
699        bool doSave = true;
700        if ( access( fd->szFullFile, F_OK ) == 0 )
701        {
702            char *t = newstrdupL( MSGS_WARNING );
703            char *m = newstrdupL( MSGS_OVERWRITE_FILE );
704            ULONG response = WinMessageBox( HWND_DESKTOP, hWndFrame, m, t,
705                                            0, MB_YESNO | MB_WARNING | MB_MOVEABLE );
706            delete m;
707            delete t;
708
709            doSave = ( response == MBID_YES );
710        }
711        if ( doSave )
712        {
713            if ( !( saved = doc->saveAs( ev, fd->szFullFile ) ) )
714            {
715                char *m = newstrdupL( MSGS_FILE_SAVE_ERROR );
716                WinMessageBox( HWND_DESKTOP, hWndFrame, m, NULL,
717                               0, MB_OK | MB_ERROR | MB_MOVEABLE );
718                delete m;
719            }
720            else
721            {
722                if ( stricmp( docFullName, fd->szFullFile ) == 0 )
723                    docViewer->resetModifiedState();
724            }
725        }
726    }
727    delete fd;
728
729    return saved;
730}
731
732void Lucide::checkNavpane()
733{
734    if ( Lucide::showIndex ) {
735        WinCheckMenuItem( hWndMenu, CM_NAVPANE, TRUE );
736        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_NAVPANE ), (MPARAM)TRUE );
737    }
738    else {
739        WinCheckMenuItem( hWndMenu, CM_NAVPANE, FALSE );
740        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_NAVPANE ), (MPARAM)FALSE );
741    }
742}
743
744
745void Lucide::toggleMaxviewFullscreen( bool maxview, bool atStartup )
746{
747    enum TriState { NoChange, On, Off };
748    TriState maxviewState = NoChange;
749    TriState fullscreenState = NoChange;
750
751    if ( maxview )
752    {
753        // maxview command issued
754        if ( !isMaxview )
755        {
756            if ( isFullscreen ) {
757                fullscreenState = Off;
758                isFullscreen = false;
759            } else {
760                maxviewState = On;
761            }
762            isMaxview = true;
763        }
764        else
765        {
766            if ( isFullscreen ) {
767                fullscreenState = Off;
768                isFullscreen = false;
769            } else {
770                maxviewState = Off;
771                isMaxview = false;
772            }
773        }
774    }
775    else
776    {
777        // fullscreen command issued
778        if ( !isFullscreen )
779        {
780            fullscreenState = On;
781            if ( !isMaxview )
782                maxviewState = On;
783        }
784        else
785        {
786            fullscreenState = Off;
787            if ( !isMaxview )
788                maxviewState = Off;
789        }
790
791        isFullscreen = !isFullscreen;
792    }
793
794    ULONG ulFrameStyle = WinQueryWindowULong( hWndFrame, QWL_STYLE );
795
796    if ( fullscreenState == Off )
797    {
798        docViewer->setFullscreen( false );
799        WinSetParent( hWndMenu, hWndFrame, FALSE );
800    }
801    else if ( fullscreenState == On )
802    {
803        docViewer->setFullscreen( true );
804        WinSetParent( hWndMenu, HWND_OBJECT, FALSE );
805    }
806
807    if ( maxviewState == Off )
808    {
809        WinSetParent( hFrameSysmenu,  hWndFrame, FALSE );
810        WinSetParent( hFrameTitlebar, hWndFrame, FALSE );
811        WinSetParent( hFrameMinMax,   hWndFrame, FALSE );
812        ulFrameStyle |= FS_SIZEBORDER;
813    }
814    else if ( maxviewState == On )
815    {
816        if ( !atStartup )
817        {
818            WinQueryWindowPos( hWndFrame, &winPos.Swp );
819            winPos.XRestore  = WinQueryWindowUShort( hWndFrame, QWS_XRESTORE );
820            winPos.YRestore  = WinQueryWindowUShort( hWndFrame, QWS_YRESTORE );
821            winPos.CXRestore = WinQueryWindowUShort( hWndFrame, QWS_CXRESTORE );
822            winPos.CYRestore = WinQueryWindowUShort( hWndFrame, QWS_CYRESTORE );
823            winPos.XMinimize = WinQueryWindowUShort( hWndFrame, QWS_XMINIMIZE );
824            winPos.YMinimize = WinQueryWindowUShort( hWndFrame, QWS_YMINIMIZE );
825        }
826
827        WinSetParent( hFrameSysmenu,  HWND_OBJECT, FALSE );
828        WinSetParent( hFrameTitlebar, HWND_OBJECT, FALSE );
829        WinSetParent( hFrameMinMax,   HWND_OBJECT, FALSE );
830        ulFrameStyle &= ~FS_SIZEBORDER;
831    }
832
833    if ( maxviewState != NoChange || fullscreenState != NoChange )
834    {
835        WinSetWindowULong( hWndFrame, QWL_STYLE, ulFrameStyle );
836        WinSendMsg( hWndFrame, WM_UPDATEFRAME, MPVOID, MPVOID );
837    }
838
839    if ( fullscreenState == Off )
840    {
841        WinSendMsg( hVertSplitter, SBM_SETSPLITTERSIZE, MPFROMSHORT( -1 ), MPVOID );
842        WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS,
843                    MPFROMSHORT( Lucide::showIndex ? Lucide::splitterPos : 0 ), MPVOID );
844        WinSendMsg( hHorizSplitter, SBM_SETFIXEDSIZE,
845            MPFROMSHORT( DEFAULT_PICTSIZE + TOOLBAR_HEIGHT_ADD ), MPVOID );
846    }
847    else if ( fullscreenState == On )
848    {
849        WinSendMsg( hHorizSplitter, SBM_SETSPLITTERPOS, 0, MPVOID );
850        WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS, 0, MPVOID );
851        WinSendMsg( hVertSplitter, SBM_SETSPLITTERSIZE, 0, MPVOID );
852    }
853
854    if ( maxviewState == Off )
855    {
856        WinSetWindowUShort( hWndFrame, QWS_XRESTORE,  winPos.XRestore );
857        WinSetWindowUShort( hWndFrame, QWS_YRESTORE,  winPos.YRestore );
858        WinSetWindowUShort( hWndFrame, QWS_CXRESTORE, winPos.CXRestore );
859        WinSetWindowUShort( hWndFrame, QWS_CYRESTORE, winPos.CYRestore );
860        WinSetWindowUShort( hWndFrame, QWS_XMINIMIZE, winPos.XMinimize );
861        WinSetWindowUShort( hWndFrame, QWS_YMINIMIZE, winPos.YMinimize );
862        WinSetWindowPos( hWndFrame, NULLHANDLE,
863                         winPos.Swp.x, winPos.Swp.y, winPos.Swp.cx, winPos.Swp.cy,
864                         SWP_SIZE | SWP_MOVE | SWP_SHOW );
865    }
866    else if ( maxviewState == On )
867    {
868        WinSetWindowPos( hWndFrame, NULLHANDLE, 0, 0,
869                         WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ),
870                         WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ),
871                         SWP_SIZE | SWP_MOVE | SWP_SHOW );
872    }
873}
874
875
876void Lucide::focusDocview()
877{
878    WinSetFocus( HWND_DESKTOP, docViewer->getViewHWND() );
879}
880
881void Lucide::focusIndex()
882{
883    WinSetFocus( HWND_DESKTOP, indexWin->getIndexHWND() );
884}
885
886void Lucide::cmdSwitchWindow()
887{
888    if ( activeWindow == AwIndex ) {
889        focusDocview();
890    } else {
891        focusIndex();
892    }
893}
894
895void Lucide::toggleZoom()
896{
897    if ( ( doc != NULL ) && doc->isScalable( ev ) )
898    {
899        bool isZoom = !docViewer->isZoomMode();
900        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_ZOOM_IN_OUT ), (MPARAM)isZoom );
901        docViewer->setZoomMode( isZoom );
902    }
903}
904
905void Lucide::cmdMinimize()
906{
907    if ( isFullscreen ) {
908        toggleFullscreen();
909    }
910    WinSetWindowPos( hWndFrame, HWND_TOP, 0, 0, 0, 0, SWP_MINIMIZE );
911}
912
913void Lucide::cmdSwitchToFullscreen()
914{
915    if ( !isFullscreen )
916    {
917        SWP pos = {0};
918        WinQueryWindowPos( hWndFrame, &pos );
919
920        if ( pos.fl & SWP_MINIMIZE ) {
921            WinSetWindowPos( hWndFrame, HWND_TOP, 0, 0, 0, 0,
922                    SWP_SHOW | SWP_ACTIVATE | SWP_RESTORE | SWP_ZORDER );
923        }
924        toggleFullscreen();
925    }
926}
927
928void Lucide::newWindow( char *file, bool addDir )
929{
930    char *param = NULL;
931
932    if ( file != NULL )
933    {
934        if ( addDir )
935        {
936            param = new char[ CCHMAXPATH ];
937            strcpy( param, docFullName );
938            char *lastSlash = strrchr( param, '\\' );
939            if ( lastSlash != NULL ) {
940                *( lastSlash + 1 ) = 0;
941            }
942            strcat( param, file );
943        }
944        else {
945            param = newstrdup( file );
946        }
947    }
948
949#if defined(__WATCOM__)
950    const char *execname = __argv[0];
951#else
952    char execname[ _MAX_PATH ];
953    _execname( execname, sizeof(execname) );
954#endif
955
956    PROGDETAILS pd;
957    pd.Length                      = sizeof( PROGDETAILS );
958    pd.progt.progc                 = PROG_DEFAULT;
959    pd.progt.fbVisible             = SHE_VISIBLE;
960    pd.pszTitle                    = NULL;
961    pd.pszExecutable               = execname;
962    pd.pszParameters               = NULL;
963    pd.pszStartupDir               = NULL;
964    pd.pszIcon                     = NULL;
965    pd.pszEnvironment              = NULL;
966    pd.swpInitial.fl               = SWP_ACTIVATE;
967    pd.swpInitial.cy               = 0;
968    pd.swpInitial.cx               = 0;
969    pd.swpInitial.y                = 0;
970    pd.swpInitial.x                = 0;
971    pd.swpInitial.hwndInsertBehind = HWND_TOP;
972    pd.swpInitial.hwnd             = NULLHANDLE;
973    pd.swpInitial.ulReserved1      = 0;
974    pd.swpInitial.ulReserved2      = 0;
975
976    WinStartApp( NULLHANDLE, &pd, param, NULL, 0 );
977
978    delete param;
979}
980
981void Lucide::gotoFile( FileList file )
982{
983    if ( fileList.size() == 0 ) {
984        return;
985    }
986
987    if ( fileListIterator == fileList.end() ) {
988        // If viewed file extension not in supported extensions
989        //   list - fileListIterator will equal fileList.end()
990        fileListIterator = fileList.begin();
991    }
992
993    if ( file == ListFirst ) {
994        fileListIterator = fileList.begin();
995    }
996    else if ( file == ListPrevious )
997    {
998        if ( fileListIterator == fileList.begin() ) {
999            fileListIterator = fileList.end();
1000        }
1001        fileListIterator--;
1002    }
1003    else if ( file == ListNext )
1004    {
1005        fileListIterator++;
1006        if ( fileListIterator == fileList.end() ) {
1007            fileListIterator = fileList.begin();
1008        }
1009    }
1010    else if ( file == ListLast ) {
1011        fileListIterator = fileList.end();
1012        fileListIterator--;
1013    }
1014
1015    std::string fname = *fileListIterator;
1016    char *fn = new char[ CCHMAXPATH ];
1017    strcpy( fn, docDirName );
1018    strcat( fn, fname.c_str() );
1019
1020    loadDocument( fn );
1021    delete fn;
1022}
1023
1024void Lucide::savePosition()
1025{
1026    if ( !WinIsWindow( hab, hWndFrame ) )
1027        return;
1028
1029    char valbuf[ 3 ] = "";
1030    PrfWriteProfileString( HINI_USERPROFILE, appName, prfSplpos,
1031                           itoa( Lucide::splitterPos, valbuf, 10 ) );
1032    PrfWriteProfileString( HINI_USERPROFILE, appName, prfShowind,
1033                           itoa( Lucide::showIndex, valbuf, 10 ) );
1034
1035    if ( isMaxview )
1036        PrfWriteProfileString( HINI_USERPROFILE, appName, prfMaxView, "1" );
1037    else
1038        PrfWriteProfileString( HINI_USERPROFILE, appName, prfMaxView, NULL );
1039
1040    if ( isFullscreen )
1041        PrfWriteProfileString( HINI_USERPROFILE, appName, prfFs, "1" );
1042    else
1043        PrfWriteProfileString( HINI_USERPROFILE, appName, prfFs, NULL );
1044
1045    if ( !isMaxview && !isFullscreen ) {
1046        WinQueryWindowPos( hWndFrame, &winPos.Swp );
1047        winPos.XRestore  = WinQueryWindowUShort( hWndFrame, QWS_XRESTORE );
1048        winPos.YRestore  = WinQueryWindowUShort( hWndFrame, QWS_YRESTORE );
1049        winPos.CXRestore = WinQueryWindowUShort( hWndFrame, QWS_CXRESTORE );
1050        winPos.CYRestore = WinQueryWindowUShort( hWndFrame, QWS_CYRESTORE );
1051        winPos.XMinimize = WinQueryWindowUShort( hWndFrame, QWS_XMINIMIZE );
1052        winPos.YMinimize = WinQueryWindowUShort( hWndFrame, QWS_YMINIMIZE );
1053    }
1054
1055    PrfWriteProfileData( HINI_USERPROFILE, appName, prfFwp, &winPos, sizeof( winPos ) );
1056}
1057
1058void Lucide::restorePosition()
1059{
1060    splitterPos = PrfQueryProfileInt( HINI_USERPROFILE, appName, prfSplpos,
1061                                      Lucide::splitterPos );
1062    showIndex = PrfQueryProfileInt( HINI_USERPROFILE, appName, prfShowind,
1063                                    Lucide::showIndex );
1064
1065    WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS,
1066                MPFROMSHORT( showIndex ? splitterPos : 0 ), MPVOID );
1067
1068    bool maxview = PrfQueryProfileInt( HINI_USERPROFILE, appName, prfMaxView, 0 ) == 1;
1069    bool fullscreen = PrfQueryProfileInt( HINI_USERPROFILE, appName, prfFs, 0 ) == 1;
1070
1071    LONG sx, sy;
1072    sx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
1073    sy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
1074
1075    ULONG SwpOptions = SWP_MOVE | SWP_SIZE | SWP_ACTIVATE | SWP_SHOW;
1076    bool atStartup = true;
1077
1078    ULONG ulWpSize = sizeof( winPos );
1079    if ( PrfQueryProfileData( HINI_USERPROFILE, appName, prfFwp, &winPos, &ulWpSize ) )
1080    {
1081        if ( winPos.Swp.fl & SWP_MAXIMIZE ) {
1082            SwpOptions |= SWP_MAXIMIZE;
1083        }
1084        else if ( winPos.Swp.fl & SWP_MINIMIZE ) {
1085            SwpOptions |= SWP_MINIMIZE;
1086        }
1087
1088        LONG sx, sy;
1089        sx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
1090        sy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
1091
1092        if ( winPos.Swp.x > sx ) {
1093            winPos.Swp.x = sx - winPos.Swp.cx;
1094        }
1095        if ( winPos.Swp.y > sy ) {
1096            winPos.Swp.y = sy - winPos.Swp.cy;
1097        }
1098
1099        // Just a note: the FID_CLIENT window is only resized by WinSetWindowPos()
1100        // on the frame if the size is actually changed *and* the SWP_SHOW flag
1101        // is present (PM bug?). Therefore, when the saved normal size the same
1102        // as fullscreen and we should go fullscreen at startup, WinSetWindowPos()
1103        // issued from toggleMaxviewFullscreen() will not resize FID_CLIENT even
1104        // though it will contain SWP_SHOW
1105
1106        if ( !maxview && !fullscreen ) {
1107            // only set the normal size if no if fullscreen or presentation is
1108            // requested, to avoid flicker. We could also avoid flicker by
1109            // omitting SWP_SHOW but see the note above
1110            WinSetWindowPos( hWndFrame, NULLHANDLE,
1111                             winPos.Swp.x, winPos.Swp.y, winPos.Swp.cx, winPos.Swp.cy,
1112                             SwpOptions );
1113        } else {
1114            // if we don't SWP_ACTIVATE now, then the title bar will keep the
1115            // inactive state after the user switches from fullscreen/presentation
1116            // (where the title bar is hidden) back to normal view later in this
1117            // session. Looks like a PM bug too
1118            WinSetWindowPos( hWndFrame, NULLHANDLE, 0, 0, 0, 0, SWP_ACTIVATE );
1119        }
1120
1121        WinSetWindowUShort( hWndFrame, QWS_XRESTORE,  winPos.XRestore );
1122        WinSetWindowUShort( hWndFrame, QWS_YRESTORE,  winPos.YRestore );
1123        WinSetWindowUShort( hWndFrame, QWS_CXRESTORE, winPos.CXRestore );
1124        WinSetWindowUShort( hWndFrame, QWS_CYRESTORE, winPos.CYRestore );
1125        WinSetWindowUShort( hWndFrame, QWS_XMINIMIZE, winPos.XMinimize );
1126        WinSetWindowUShort( hWndFrame, QWS_YMINIMIZE, winPos.YMinimize );
1127
1128        // we don't the app to be minimized at startup
1129        if ( SwpOptions & SWP_MINIMIZE )
1130            WinSetWindowPos( hWndFrame, NULLHANDLE, 0, 0, 0, 0, SWP_RESTORE );
1131    }
1132    else
1133    {
1134        typedef
1135        BOOL ( APIENTRY *WinQueryDesktopWorkArea_T ) ( HWND hwndDesktop,
1136                                                       PRECTL pwrcWorkArea );
1137        static WinQueryDesktopWorkArea_T WinQueryDesktopWorkArea =
1138            (WinQueryDesktopWorkArea_T) ~0;
1139
1140        if ( (ULONG) WinQueryDesktopWorkArea == (ULONG) ~0 ) {
1141            if ( my_DosQueryProcAddr( "PMMERGE", 5469,
1142                                      (PFN *) &WinQueryDesktopWorkArea ) )
1143                WinQueryDesktopWorkArea = NULL;
1144        }
1145
1146        SWP swp;
1147        RECTL rcl;
1148        if ( WinQueryDesktopWorkArea &&
1149             WinQueryDesktopWorkArea( HWND_DESKTOP, &rcl ) ) {
1150            swp.x = rcl.xLeft;
1151            swp.y = rcl.yBottom;
1152            swp.cx = rcl.xRight - rcl.xLeft;
1153            swp.cy = rcl.yTop - rcl.yBottom;
1154        } else {
1155            swp.x = 0;
1156            swp.y = 0;
1157            swp.cx = sx;
1158            swp.cy = sy;
1159        }
1160
1161        swp.x += 16;
1162        swp.y += 16;
1163        swp.cx -= 32;
1164        swp.cy -= 32;
1165
1166        WinSetWindowPos( hWndFrame, NULLHANDLE, swp.x, swp.y, swp.cx, swp.cy,
1167                         SwpOptions );
1168
1169        // we don't initialize winPos here so reset atStartup to let
1170        // toggleMaxviewFullscreen() do this
1171        atStartup = false;
1172    }
1173
1174    if ( fullscreen )
1175    {
1176        toggleMaxviewFullscreen( false, atStartup );
1177        isMaxview = maxview;
1178    }
1179    else if ( maxview )
1180    {
1181        toggleMaxviewFullscreen( true, atStartup );
1182    }
1183}
1184
1185static MRESULT EXPENTRY frameProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
1186{
1187    switch ( msg )
1188    {
1189        case WM_TRANSLATEACCEL:
1190        {
1191            // change the accel logic by first letting the focus window process
1192            // WM_CHAR and only translate it to accel if not handled (this makes
1193            // sure that keyboard shortcuts in input fields work even if we
1194            // defined our own accelerators from these shortcuts)
1195            PQMSG pqmsg = (PQMSG)mp1;
1196            HWND focus = WinQueryFocus( HWND_DESKTOP );
1197            if ( focus == pqmsg->hwnd && focus != hwnd ) {
1198                if ( WinDispatchMsg( hab, pqmsg ) ) {
1199                    pqmsg->msg = WM_NULL;
1200                    return (MRESULT)TRUE;
1201                }
1202            }
1203            // in fullscreen, we hide the menu which effectively makes all
1204            // disabled items work through accelerators which is completely
1205            // unexpected. Fix it by translating accels manually and checking
1206            // if they are disabled in the hidden menu
1207            if ( WinTranslateAccel( hab, hwnd, WinQueryAccelTable( hab, hwnd ),
1208                                    pqmsg ) ) {
1209                if ( pqmsg->msg == WM_COMMAND ) {
1210                    SHORT cm = SHORT1FROMMP(pqmsg->mp1);
1211                    if ( !WinIsMenuItemEnabled( hWndMenu, cm ) )
1212                        pqmsg->msg = WM_NULL;
1213                }
1214                return (MRESULT)TRUE;
1215            }
1216            return (MRESULT)FALSE;
1217        }
1218
1219        case WM_SYSCOMMAND:
1220        {
1221            if ( SHORT1FROMMP(mp1) == SC_CLOSE ) {
1222                // the system menu is disabled in fullscreen/presentation mode
1223                // but we still want to exit with Alt-F4 so always handle it here
1224                WinPostMsg( hWndFrame, WM_CLOSE, NULL, NULL );
1225                return (MRESULT)FALSE;
1226            }
1227        }
1228        break;
1229    }
1230
1231    return pOldFrameProc( hwnd, msg, mp1, mp2 );
1232}
1233
1234static MRESULT EXPENTRY splProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
1235{
1236    switch ( msg )
1237    {
1238        case WM_CONTROL:
1239        {
1240            if ( ( SHORT1FROMMP( mp1 ) == ID_SPLITTER ) &&
1241                 ( SHORT2FROMMP( mp1 ) == SBN_POSITIONCHANGED ) )
1242            {
1243                SHORT pos = SHORT1FROMMP( mp2 );
1244                if ( pos > 0 ) {
1245                    Lucide::splitterPos = pos;
1246                    Lucide::showIndex = true;
1247                }
1248                else {
1249                    Lucide::showIndex = false;
1250                }
1251                Lucide::checkNavpane();
1252            }
1253        }
1254        break;
1255
1256        case WM_COMMAND:
1257        {
1258            switch ( SHORT1FROMMP(mp1) )
1259            {
1260                case CM_NEW_WINDOW:
1261                    Lucide::newWindow( NULL, false );
1262                    return (MRESULT)FALSE;
1263
1264                case CM_OPEN:
1265                    Lucide::openDocument();
1266                    return (MRESULT)FALSE;
1267
1268                case CM_FILEFIRST:
1269                    Lucide::gotoFile( ListFirst );
1270                    return (MRESULT)FALSE;
1271
1272                case CM_FILEPREVIOUS:
1273                    Lucide::gotoFile( ListPrevious );
1274                    return (MRESULT)FALSE;
1275
1276                case CM_FILENEXT:
1277                    Lucide::gotoFile( ListNext );
1278                    return (MRESULT)FALSE;
1279
1280                case CM_FILELAST:
1281                    Lucide::gotoFile( ListLast );
1282                    return (MRESULT)FALSE;
1283
1284                case CM_RECENT + 1:
1285                case CM_RECENT + 2:
1286                case CM_RECENT + 3:
1287                case CM_RECENT + 4:
1288                case CM_RECENT + 5:
1289                case CM_RECENT + 6:
1290                case CM_RECENT + 7:
1291                case CM_RECENT + 8:
1292                case CM_RECENT + 9:
1293                {
1294                    std::string f = recent->getFile( SHORT1FROMMP(mp1) );
1295                    Lucide::loadDocument( f.c_str() );
1296                    return (MRESULT)FALSE;
1297                }
1298
1299                case CM_RECENTCLEAR:
1300                    recent->clear();
1301                    return (MRESULT)FALSE;
1302
1303                case CM_SAVEAS:
1304                    Lucide::saveDocumentAs();
1305                    return (MRESULT)FALSE;
1306
1307                case CM_CLOSE:
1308                    Lucide::closeDocument();
1309                    return (MRESULT)FALSE;
1310
1311                case CM_PRINT:
1312                {
1313                    PrintDlg *d = new PrintDlg( hWndFrame, doc, Lucide::docFileName,
1314                                                docViewer->getCurrentPage() + 1 );
1315                    if ( d->showDialog() == DID_OK )
1316                    {
1317                        // print
1318                        PrintSetup *p = new PrintSetup;
1319                        memset( p, 0, sizeof( PrintSetup ) );
1320                        d->getPrintSetup( p );
1321                        printDocument( hWndFrame, doc, Lucide::docFileName, p );
1322                        delete p;
1323                    }
1324                    delete d;
1325                    return (MRESULT)FALSE;
1326                }
1327
1328                case CM_EXIT:
1329                    WinPostMsg( hWndFrame, WM_CLOSE, NULL, NULL );
1330                    return (MRESULT)FALSE;
1331
1332                case CM_DOCINFO:
1333                {
1334                    LuDocumentInfo *dinfo = doc->getDocumentInfo( ev );
1335                    DocInfoDlg *d = new DocInfoDlg( hWndFrame, dinfo );
1336                    d->doDialog();
1337                    LuDocument::freeDocumentInfo( ev, dinfo );
1338                    return (MRESULT)FALSE;
1339                }
1340
1341                case CM_FONTSINFO:
1342                {
1343                    FontsInfoDlg *d = new FontsInfoDlg( hWndFrame, doc );
1344                    d->doDialog();
1345                    return (MRESULT)FALSE;
1346                }
1347
1348                case CM_PLUGINSLIST:
1349                {
1350                    PluginViewDlg *d = new PluginViewDlg( hWndFrame,
1351                                                pluginMan->getPluginsList() );
1352                    d->doDialog();
1353                    return (MRESULT)FALSE;
1354                }
1355
1356                case CM_COPY:
1357                    docViewer->copyToClipbrd();
1358                    return (MRESULT)FALSE;
1359
1360                case CM_SELECTALL:
1361                    docViewer->selectAll();
1362                    return (MRESULT)FALSE;
1363
1364                case CM_FIND:
1365                    if ( findDlg->showDialog() == DID_OK ) {
1366                        if ( strlen( findDlg->getSearchString() ) > 0 )
1367                        {
1368                            docViewer->searchDocument( findDlg->getSearchString(),
1369                                            findDlg->isCaseSensitive(), false );
1370
1371                            WinEnableMenuItem( hWndMenu, CM_FINDAGAIN, TRUE );
1372                            WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FINDAGAIN), (MPARAM)TRUE );
1373                        }
1374                    }
1375                    return (MRESULT)FALSE;
1376
1377                case CM_FINDAGAIN:
1378                    docViewer->searchDocument( findDlg->getSearchString(),
1379                                               findDlg->isCaseSensitive(), true );
1380                    return (MRESULT)FALSE;
1381
1382                case CM_SETTINGS:
1383                {
1384                    SettingsDlg *d = new SettingsDlg( hWndFrame, settings );
1385                    d->doDialog();
1386                    return (MRESULT)FALSE;
1387                }
1388
1389                case CM_FIRSTPAGE:
1390                    Lucide::goToPage( 0 );
1391                    return (MRESULT)FALSE;
1392
1393                case CM_NEXTPAGE:
1394                    Lucide::goToPage( docViewer->getCurrentPage() + 1 );
1395                    return (MRESULT)FALSE;
1396
1397                case CM_PREVPAGE:
1398                    Lucide::goToPage( docViewer->getCurrentPage() - 1 );
1399                    return (MRESULT)FALSE;
1400
1401                case CM_LASTPAGE:
1402                    Lucide::goToPage( doc->getPageCount( ev ) - 1 );
1403                    return (MRESULT)FALSE;
1404
1405                case CM_GOTOPAGE:
1406                {
1407                    GotoDlg *d = new GotoDlg( hWndFrame, doc->getPageCount( ev ),
1408                                                docViewer->getCurrentPage() + 1 );
1409                    if ( d->showDialog() == DID_OK ) {
1410                        long pg = d->getPage();
1411                        if ( pg > 0 ) {
1412                            Lucide::goToPage( pg - 1 );
1413                        }
1414                    }
1415                    delete d;
1416                    return (MRESULT)FALSE;
1417                }
1418
1419                case CM_FITWINDOW:
1420                    Lucide::setZoom( -2 );
1421                    return (MRESULT)FALSE;
1422
1423                case CM_ACTSIZE:
1424                    Lucide::setZoom( 1 );
1425                    return (MRESULT)FALSE;
1426
1427                case CM_FITWIDTH:
1428                    Lucide::setZoom( -1 );
1429                    return (MRESULT)FALSE;
1430
1431                case CM_ZOOM_IN_OUT:
1432                    Lucide::toggleZoom();
1433                    return (MRESULT)FALSE;
1434
1435                case CM_ZOOM_IN:
1436                    docViewer->zoomInOut( true );
1437                    return (MRESULT)FALSE;
1438
1439                case CM_ZOOM_OUT:
1440                    docViewer->zoomInOut( false );
1441                    return (MRESULT)FALSE;
1442
1443                case CM_SINGLEPAGE:
1444                    Lucide::setPageLayout( SinglePage );
1445                    return (MRESULT)FALSE;
1446
1447                case CM_CONTINUOUS:
1448                    Lucide::setPageLayout( Continuous );
1449                    return (MRESULT)FALSE;
1450
1451                case CM_ROTATE90CW:
1452                    docViewer->setRotation( docViewer->getRotation() + 90 );
1453                    return (MRESULT)FALSE;
1454
1455                case CM_ROTATE90CCW:
1456                    docViewer->setRotation( docViewer->getRotation() - 90 );
1457                    return (MRESULT)FALSE;
1458
1459                case CM_NAVPANE:
1460                    {
1461                        Lucide::showIndex = !Lucide::showIndex;
1462                        Lucide::checkNavpane();
1463                        WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS,
1464                            MPFROMSHORT( Lucide::showIndex ? Lucide::splitterPos : 0 ), MPVOID );
1465                        if ( !Lucide::showIndex ) {
1466                            Lucide::focusDocview();
1467                        }
1468                    }
1469                    return (MRESULT)FALSE;
1470
1471                case CM_MAXVIEW:
1472                    Lucide::toggleMaxview();
1473                    return (MRESULT)FALSE;
1474
1475                case CM_FULLSCREEN:
1476                    Lucide::toggleFullscreen();
1477                    return (MRESULT)FALSE;
1478
1479                case CM_PRODINFO:
1480                    AboutBox( hWndFrame );
1481                    return (MRESULT)FALSE;
1482
1483                case CM_MINIMIZE:
1484                    Lucide::cmdMinimize();
1485                    return (MRESULT)FALSE;
1486
1487                case CM_TOFULLSCREEN:
1488                    Lucide::cmdSwitchToFullscreen();
1489                    return (MRESULT)FALSE;
1490
1491                case CM_SWITCHWINDOW:
1492                    Lucide::cmdSwitchWindow();
1493                    return (MRESULT)FALSE;
1494            }
1495        }
1496        break;
1497
1498        case WM_CLOSE:
1499            if ( !Lucide::closeDocument() )
1500                return (MRESULT)FALSE;
1501        break;
1502    }
1503    return pOldSplProc( hwnd, msg, mp1, mp2 );
1504}
1505
1506
1507char deffont[] = "9.WarpSans";
1508int deffontlen = sizeof( deffont );
1509
1510__declspec(dllexport) _System APIRET APIENTRY LucideMain( int argc, char *argv[] )
1511{
1512    HMQ   hmq;
1513    QMSG  qmsg;
1514    hab = WinInitialize( 0 );
1515    hmq = WinCreateMsgQueue( hab, 0 );
1516
1517    loadLang();
1518
1519    settings = new LuSettings;
1520    settings->load();
1521
1522    pluginMan = new PluginManager;
1523
1524    InitPMSplitterClass( hab );
1525    InitPMToolbarClass( hab );
1526
1527    ULONG ulFrameFlags = FCF_TITLEBAR | FCF_SIZEBORDER | FCF_SYSMENU |
1528                         FCF_MINMAX | FCF_TASKLIST | FCF_NOBYTEALIGN | FCF_ICON;
1529    title = newstrdupL( MSGS_MAIN_WIN_TITLE );
1530    hWndFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &ulFrameFlags, NULL, title,
1531                                    WS_SYNCPAINT|WS_VISIBLE, _hmod, IDI_MAIN_ICON, NULL );
1532    pOldFrameProc = WinSubclassWindow( hWndFrame, frameProc );
1533
1534    hFrameSysmenu  = WinWindowFromID( hWndFrame, FID_SYSMENU );
1535    hFrameTitlebar = WinWindowFromID( hWndFrame, FID_TITLEBAR );
1536    hFrameMinMax   = WinWindowFromID( hWndFrame, FID_MINMAX );
1537    WinSetAccelTable( hab, WinLoadAccelTable( hab, _hmod, IDA_MAINACCEL ), hWndFrame );
1538    hWndMenu = WinLoadMenu( hWndFrame, _hmod, IDM_MAINMENU );
1539    localizeMenu( hWndMenu );
1540    WinSetWindowUShort( hWndMenu, QWS_ID, FID_MENU );
1541
1542    // Vertical splitter and his windows - Index and Document view
1543    hVertSplitter = WinCreateWindow( hWndFrame, WC_ER_SPLITTER, "",
1544                                     WS_VISIBLE | SBS_VSPLIT,
1545                                     0, 0, 0, 0, hWndFrame, HWND_TOP,
1546                                     ID_SPLITTER, NULL, NULL );
1547
1548    indexWin = new IndexWindow( hWndFrame );
1549
1550    DocumentViewer::registerClass();
1551
1552    docViewer = new DocumentViewer( hWndFrame );
1553
1554    WinSendMsg( hVertSplitter, SBM_SETWINDOWS,
1555                MPFROMHWND( indexWin->getHWND() ), MPFROMHWND( docViewer->getFrameHWND() ) );
1556
1557    // Horizontal splitter and its windows - Toolbar and Vertical splitter
1558    // Horizontal splitter is client window
1559    hHorizSplitter = WinCreateWindow( hWndFrame, WC_ER_SPLITTER, "",
1560                                      WS_VISIBLE | SBS_HSPLIT | SBS_SECONDFIXED,
1561                                      0, 0, 0, 0, hWndFrame, HWND_TOP,
1562                                      FID_CLIENT, NULL, NULL );
1563    pOldSplProc = WinSubclassWindow( hHorizSplitter, splProc );
1564
1565    hToolBar = createToolbar( hWndFrame );
1566
1567    WinSendMsg( hHorizSplitter, SBM_SETWINDOWS,
1568                MPFROMHWND( hVertSplitter ), MPFROMHWND( hToolBar ) );
1569    // ᅵᅵ⠭ᅵᅵᅵᅵᅵ 䚪ᅵ஢ᅵᅵᅵᅵ ࠧᅵᅵᅵ ᅵᅵᅵ ᅵ㫡ᅵᅵ
1570    WinSendMsg( hHorizSplitter, SBM_SETFIXEDSIZE,
1571                MPFROMSHORT( DEFAULT_PICTSIZE + TOOLBAR_HEIGHT_ADD ), MPVOID );
1572
1573    Lucide::checkMenus( true );
1574    Lucide::setPageLayout( settings->layout );
1575    Lucide::setZoom( settings->zoom );
1576
1577    findDlg = new FindDlg( hWndFrame );
1578    recent  = new RecentFiles( hWndMenu );
1579
1580    Lucide::restorePosition();
1581
1582    Lucide::focusDocview();
1583
1584    if ( argc > 1 ) {
1585        Lucide::loadDocument( argv[1] );
1586    }
1587
1588    Lucide::checkNavpane();
1589    initPipeMon( hWndFrame );
1590
1591    // Messsage loop
1592    while ( WinGetMsg( hab, &qmsg, 0, 0, 0 ) ) {
1593        WinDispatchMsg( hab, &qmsg );
1594    }
1595
1596    Lucide::savePosition();
1597
1598    WinDestroyWindow( hWndFrame );
1599
1600    recent->save();
1601
1602    Lucide::closeDocument( true );
1603    delete docViewer;
1604    delete indexWin;
1605
1606    // must be freed _after_ document
1607    delete pluginMan;
1608
1609    delete findDlg;
1610    delete recent;
1611    delete title;
1612    delete settings;
1613    unInitPipeMon();
1614
1615    WinDestroyMsgQueue( hmq );
1616    WinTerminate( hab );
1617    return 0;
1618}
1619
Note: See TracBrowser for help on using the repository browser.