source: trunk/Lucide/gui/lucide.cpp

Last change on this file was 704, checked in by Gregg Young, 2 years ago

Fix failure to open encrypted files

File size: 75.3 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#define INCL_WIN
35#define INCL_SPL
36#define INCL_SPLDOSPRINT
37#include "os2all.h"
38
39#include <string>
40#include <vector>
41#include <algorithm>
42#include <stdio.h>
43#include <stdlib.h>
44#include <process.h>
45#if defined(__WATCOM__)
46#include <dos.h>
47#define find_t_name(find_t) find_t.name
48#else
49#include <unistd.h>
50#include <emx/syscalls.h>
51typedef _find find_t;
52#define find_t_name(find_t) find_t.szName
53#define _dos_findfirst __findfirst
54#define _dos_findnext __findnext
55#define _dos_findclose(a) do {} while(0)
56#endif
57
58#include <ludoc.xh>
59
60#include "Lucide.h"
61#include "pluginman.h"
62#include "pluginViewDlg.h"
63#include "fontsInfoDlg.h"
64#include "docInfoDlg.h"
65#include "findDlg.h"
66#include "printDlg.h"
67#include "progressDlg.h"
68#include "settingsDlg.h"
69#include "passwordDlg.h"
70#include "docViewer.h"
71#include "indexWindow.h"
72#include "recent.h"
73#include "lusettings.h"
74#include "luutils.h"
75#include "tb_spl.h"
76#include "Lucide_res.h"
77#include "messages.h"
78
79//#define INCL_EXCEPTQ_CLASS
80//#define INCL_LOADEXCEPTQ
81//#include "exceptq.h"
82
83#define ID_SPLITTER 1
84
85const char *appName    = "Lucide";
86const char *appVersion = VERSION;
87const char *appBuild   = BUILD;
88const char *appDate    = VERSIONDATE;
89const char *prfFwp     = "FrameWindowPos";
90const char *prfLvd     = "LastViewedDir";
91const char *prfSplpos  = "SplitterPos";
92const char *prfShowind = "ShowIndex";
93const char *prfFullscreen   = "FullScreen";
94const char *prfPresentation = "Presentation";
95
96HWND createToolbar( HWND hwnd );
97void AboutBox( HWND hWndFrame );
98void initPipeMon( HWND hWndFrame );
99void unInitPipeMon();
100HWND LcdFileDlg( HWND hwndP, HWND hwndO, FILEDLG *pfild );
101
102
103HAB   hab            = NULLHANDLE;
104HWND  hWndFrame      = NULLHANDLE;
105HWND  hWndMenu       = NULLHANDLE;
106HWND  hToolBar       = NULLHANDLE;
107HWND  hVertSplitter  = NULLHANDLE;
108HWND  hHorizSplitter = NULLHANDLE;
109HWND  hFrameSysmenu  = NULLHANDLE;
110HWND  hFrameTitlebar = NULLHANDLE;
111HWND  hFrameMinMax   = NULLHANDLE;
112HELPINIT hini;
113HINI hinilucideprofile;
114
115Environment    *ev        = somGetGlobalEnvironment();
116LuDocument     *doc       = NULL;
117PluginManager  *pluginMan = NULL;
118DocumentViewer *docViewer = NULL;
119IndexWindow    *indexWin  = NULL;
120FindDlg        *findDlg   = NULL;
121LuSettings     *settings  = NULL;
122RecentFiles    *recent    = NULL;
123char           *title     = NULL;
124
125
126bool         Lucide::dontSwitchPage                = false;
127SHORT        Lucide::splitterPos                   = 100;
128bool         Lucide::showIndex                     = true;
129bool         Lucide::isFullscreen                  = false;
130bool         Lucide::isPresentation                = false;
131bool         Lucide::Thumbnail                     = true;
132LuWindowPos  Lucide::winPos                        = {0};
133char         Lucide::docFullName[ CCHMAXPATH ]     = "";
134char         Lucide::docFileName[ CCHMAXPATHCOMP ] = "";
135char         Lucide::docDirName[ CCHMAXPATHCOMP ]  = "";
136char        *Lucide::password                      = NULL;
137ActiveWindow Lucide::activeWindow                  = AwView;
138// static data for asynch loading document
139ProgressDlg *Lucide::loadProgressDlg               = NULL;
140bool         Lucide::docLoaded                     = false;;
141char        *Lucide::loadError                     = NULL;
142long         Lucide::loadErrorCode                 = LU_LDERR_NO_ERROR;
143char        *Lucide::thumbnailData                 = NULL;
144int          Lucide::thumbnailDataLen              = 0;
145HWND         Lucide::hwndHelp                      = NULLHANDLE;
146
147// List of files in current directory
148static std::vector<std::string> fileList;
149static std::vector<std::string>::const_iterator fileListIterator;
150
151HMODULE _hmod = NULLHANDLE;
152
153unsigned APIENTRY LibMain( unsigned hmod, unsigned termination )
154{
155    if ( termination ) {
156        // DLL is detaching from process
157    } else {
158        // DLL is attaching to process
159        _hmod = hmod;
160    }
161    return( 1 );
162}
163
164#if !defined(__WATCOM__)
165extern "C" unsigned long _System _DLL_InitTerm( unsigned long mod_handle,
166                                                unsigned long flag )
167{
168    int _CRT_init();
169    void _CRT_term();
170    void __ctordtorInit();
171    void __ctordtorTerm();
172
173    switch ( flag ) {
174        case 0:
175            if ( _CRT_init() != 0 )
176                return 0;
177            __ctordtorInit();
178            return LibMain( mod_handle, flag );
179        case 1:
180            __ctordtorTerm();
181            _CRT_term ();
182            return LibMain( mod_handle, flag );
183        default:
184            return 0;
185    }
186}
187#endif
188
189
190// stolen from xWorkplace sources
191static
192APIRET my_DosQueryProcAddr(PCSZ pcszModuleName, ULONG ulOrdinal, PFN *ppfn)
193{
194    HMODULE hmod = NULL;
195    APIRET rc = 0;
196    if (!(rc = DosQueryModuleHandle( (PSZ)pcszModuleName, &hmod))) {
197        if ((rc = DosQueryProcAddr( hmod, ulOrdinal, NULL, ppfn))) {
198            // the CP programming guide and reference says use
199            // DosLoadModule if DosQueryProcAddr fails with this error
200            if (rc == ERROR_INVALID_HANDLE) {
201                if (!(rc = DosLoadModule(NULL, 0, (PSZ) pcszModuleName,
202                                         &hmod))) {
203                    rc = DosQueryProcAddr(hmod, ulOrdinal, NULL, ppfn);
204                }
205            }
206        }
207    }
208    return rc;
209}
210
211
212PFNWP pOldFrameProc = NULL;
213PFNWP pOldSplProc   = NULL;
214
215void Lucide::enableCopy( bool enable )
216{
217    WinEnableMenuItem( hWndMenu, CM_COPY, enable );
218}
219
220void Lucide::setOfPages( long pages )
221{
222    char pgnum[ 32 ];
223
224    // set current page
225    WinSendDlgItemMsg( hToolBar, TBID_PAGENUM, SPBM_SETLIMITS,
226                      MPFROMLONG( pages ), MPFROMLONG( 1 ) );
227
228    // set of pages
229    char *pgfrm = newstrdupL( TB_PAGENUM );
230    snprintf( pgnum, sizeof( pgnum ), pgfrm, pages );
231    delete pgfrm;
232    WinSetDlgItemText( hToolBar, TBID_OFPAGES, pgnum );
233
234}
235
236void Lucide::checkNavigationMenus()
237{
238    WinEnableMenuItem( hWndMenu, CM_GOTOPAGE, TRUE );
239    BOOL enfirst = ( docViewer->getCurrentPage() != 0 );
240    BOOL enlast = ( docViewer->getCurrentPage() != ( doc->getPageCount( ev ) - 1 ) );
241    WinEnableMenuItem( hWndMenu, CM_FIRSTPAGE, enfirst );
242    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FIRSTPAGE), (MPARAM)enfirst );
243    WinEnableMenuItem( hWndMenu, CM_PREVPAGE, enfirst );
244    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_PREVPAGE), (MPARAM)enfirst );
245    WinEnableMenuItem( hWndMenu, CM_NEXTPAGE, enlast );
246    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_NEXTPAGE), (MPARAM)enlast );
247    WinEnableMenuItem( hWndMenu, CM_LASTPAGE, enlast );
248    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_LASTPAGE), (MPARAM)enlast );
249    bool chkback = docViewer->getPreviousPage() >= 0;
250    WinEnableMenuItem( hWndMenu, CM_BACKNAV, chkback );
251
252    // set actual page
253    bool tmp = dontSwitchPage;
254    dontSwitchPage = true;
255    char pgnum[32];
256    WinSendDlgItemMsg( hToolBar, TBID_PAGENUM, SPBM_SETCURRENTVALUE,
257                               MPFROMLONG( docViewer->getCurrentPage() + 1 ), MPVOID );
258    dontSwitchPage = tmp;
259    indexWin->goToPage( NULL, docViewer->getCurrentPage() );
260}
261
262void Lucide::enableZoomMenus()
263{
264    BOOL scalable = doc->isScalable( ev );
265    WinEnableMenuItem( hWndMenu, CM_FITWINDOW, scalable );
266    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FITWINDOW), (MPARAM)scalable );
267    WinEnableMenuItem( hWndMenu, CM_ACTSIZE, scalable );
268    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_ACTSIZE), (MPARAM)scalable );
269    WinEnableMenuItem( hWndMenu, CM_FITWIDTH, scalable );
270    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FITWIDTH), (MPARAM)scalable );
271    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_ZOOM_IN_OUT), (MPARAM)scalable );
272    WinEnableMenuItem( hWndMenu, CM_ZOOM_IN, scalable );
273    WinEnableMenuItem( hWndMenu, CM_ZOOM_OUT, scalable );
274    WinEnableControl( hToolBar, TBID_ZOOM, scalable );
275    BOOL rotable = doc->isRotable( ev );
276    WinEnableMenuItem( hWndMenu, CM_ROTATE90CW, rotable );
277    WinEnableMenuItem( hWndMenu, CM_ROTATE90CCW, rotable );
278}
279
280
281void Lucide::setZoomChecks( SHORT cmd, SHORT cbind, double zoom )
282{
283    if ( cmd != -1 )
284    {
285        WinCheckMenuItem( hWndMenu, cmd, TRUE );
286        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( cmd ), (MPARAM)TRUE );
287    }
288
289    if ( cbind != -1 )
290    {
291        char buf[ 255 ] = "";
292        WinSendDlgItemMsg( hToolBar, TBID_ZOOM, LM_QUERYITEMTEXT,
293                           MPFROM2SHORT( cbind, sizeof( buf ) ), MPFROMP( buf ) );
294        WinSetDlgItemText( hToolBar, TBID_ZOOM, buf );
295    }
296
297    if ( zoom != 0 )
298    {
299        std::string z = str( zoom * 100.0 ) + "%";
300        WinSetDlgItemText( hToolBar, TBID_ZOOM, z.c_str() );
301    }
302}
303
304void Lucide::checkZoomMenus()
305{
306    double zoom = docViewer->getZoom();
307
308    WinCheckMenuItem( hWndMenu, CM_FITWINDOW, FALSE );
309    WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT(CM_FITWINDOW), (MPARAM)FALSE );
310    WinCheckMenuItem( hWndMenu, CM_ACTSIZE, FALSE );
311    WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT(CM_ACTSIZE), (MPARAM)FALSE );
312    WinCheckMenuItem( hWndMenu, CM_FITWIDTH, FALSE );
313    WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT(CM_FITWIDTH), (MPARAM)FALSE );
314
315    if ( zoom == -2 ) {
316        setZoomChecks( CM_FITWINDOW, 1, 0 );
317    } else if ( zoom == -1 ) {
318        setZoomChecks( CM_FITWIDTH, 2, 0 );
319    } else if ( zoom == 1 ) {
320        setZoomChecks( CM_ACTSIZE, 0, 0 );
321    } else {
322        setZoomChecks( -1, -1, zoom );
323    }
324}
325
326void Lucide::checkMenus( bool initial )
327{
328    if ( initial )
329    {
330        // pre-set "Actual size"
331        setZoomChecks( CM_ACTSIZE, 0, 0 );
332    }
333
334    if ( doc == NULL )
335    {
336        if ( initial )
337        {
338            // "single page" mode by default
339            WinCheckMenuItem( hWndMenu, CM_SINGLEPAGE, TRUE );
340        }
341
342        WinEnableMenuItem( hWndMenu, CM_BACK, FALSE );
343        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_BACK), (MPARAM)FALSE );
344        WinEnableMenuItem( hWndMenu, CM_SAVE, FALSE );
345        WinEnableMenuItem( hWndMenu, CM_SAVEAS, FALSE );
346        WinEnableMenuItem( hWndMenu, CM_CLOSE, FALSE );
347        WinEnableMenuItem( hWndMenu, CM_PRINT, FALSE );
348        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_PRINT), (MPARAM)FALSE );
349        WinEnableMenuItem( hWndMenu, CM_DOCINFO, FALSE );
350        WinEnableMenuItem( hWndMenu, CM_FONTSINFO, FALSE );
351
352        WinEnableMenuItem( hWndMenu, CM_COPY, FALSE );
353        WinEnableMenuItem( hWndMenu, CM_SELECTALL, FALSE );
354        WinEnableMenuItem( hWndMenu, CM_FIND, FALSE );
355        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FIND), (MPARAM)FALSE );
356        WinEnableMenuItem( hWndMenu, CM_FINDAGAIN, FALSE );
357        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FINDAGAIN), (MPARAM)FALSE );
358
359        WinEnableMenuItem( hWndMenu, CM_FIRSTPAGE, FALSE );
360        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FIRSTPAGE), (MPARAM)FALSE );
361        WinEnableMenuItem( hWndMenu, CM_PREVPAGE, FALSE );
362        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_PREVPAGE), (MPARAM)FALSE );
363        WinEnableMenuItem( hWndMenu, CM_NEXTPAGE, FALSE );
364        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_NEXTPAGE), (MPARAM)FALSE );
365        WinEnableMenuItem( hWndMenu, CM_LASTPAGE, FALSE );
366        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_LASTPAGE), (MPARAM)FALSE );
367        WinEnableMenuItem( hWndMenu, CM_GOTOPAGE, FALSE );
368        WinEnableMenuItem( hWndMenu, CM_BACKNAV, FALSE );
369
370        WinEnableMenuItem( hWndMenu, CM_FITWINDOW, FALSE );
371        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FITWINDOW), (MPARAM)FALSE );
372        WinEnableMenuItem( hWndMenu, CM_ACTSIZE, FALSE );
373        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_ACTSIZE), (MPARAM)FALSE );
374        WinEnableMenuItem( hWndMenu, CM_FITWIDTH, FALSE );
375        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FITWIDTH), (MPARAM)FALSE );
376        WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_ZOOM_IN_OUT), (MPARAM)FALSE );
377        WinEnableMenuItem( hWndMenu, CM_ZOOM_IN, FALSE );
378        WinEnableMenuItem( hWndMenu, CM_ZOOM_OUT, FALSE );
379        WinEnableControl( hToolBar, TBID_ZOOM, FALSE );
380
381        WinEnableMenuItem( hWndMenu, CM_ROTATE90CW, FALSE );
382        WinEnableMenuItem( hWndMenu, CM_ROTATE90CCW, FALSE );
383        WinEnableMenuItem( hWndMenu, CM_SINGLEPAGE, FALSE );
384        WinEnableMenuItem( hWndMenu, CM_CONTINUOUS, FALSE );
385
386        setOfPages( 0 );
387        return;
388    }
389
390
391    checkNavigationMenus();
392    enableZoomMenus();
393    checkZoomMenus();
394
395    WinEnableMenuItem( hWndMenu, CM_PRINT, TRUE );
396    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_PRINT), (MPARAM)TRUE );
397    bool chkback = docViewer->getPreviousPage() >= 0;
398    WinEnableMenuItem( hWndMenu, CM_BACK, chkback );
399    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_BACK), (MPARAM)chkback );
400    WinEnableMenuItem( hWndMenu, CM_SAVE, doc->isSaveable( ev ) &&
401                      doc->isHaveInputFields( ev ));
402    WinEnableMenuItem( hWndMenu, CM_SAVEAS, doc->isSaveable( ev ) );
403    WinEnableMenuItem( hWndMenu, CM_CLOSE, TRUE );
404    setOfPages( doc->getPageCount( ev ) );
405    WinEnableMenuItem( hWndMenu, CM_FONTSINFO, doc->isHaveFontInfo( ev ) );
406    WinEnableMenuItem( hWndMenu, CM_DOCINFO, TRUE );
407
408    BOOL haveText = doc->isHaveText( ev );
409    WinEnableMenuItem( hWndMenu, CM_FIND, haveText );
410    WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FIND), (MPARAM)haveText );
411    WinEnableMenuItem( hWndMenu, CM_SELECTALL, haveText );
412
413    WinEnableMenuItem( hWndMenu, CM_SINGLEPAGE, TRUE );
414    WinEnableMenuItem( hWndMenu, CM_CONTINUOUS, TRUE );
415}
416
417void Lucide::goToPage( long page )
418{
419    if ( docViewer != NULL ) {
420       if (page > (doc->getPageCount(ev) -1)) {
421                page = doc->getPageCount(ev) -1;
422       }
423        docViewer->goToPage( page );
424    }
425}
426
427long Lucide::pageCount( void )
428{
429    if ( doc != NULL ) {
430        return doc->getPageCount( ev );
431    } else {
432        return 0;
433    }
434}
435
436void Lucide::setZoom( double zoom )
437{
438    if ( docViewer != NULL ) {
439        docViewer->setZoom( zoom );
440        checkZoomMenus();
441    }
442}
443
444void Lucide::setDocument( LuDocument *_doc )
445{
446    docViewer->setDocument( _doc );
447    indexWin->setDocument( _doc );
448    checkMenus( false );
449}
450
451void Lucide::setPageLayout( PgLayout layout )
452{
453    if ( layout == SinglePage ) {
454        WinCheckMenuItem( hWndMenu, CM_SINGLEPAGE, TRUE );
455        WinCheckMenuItem( hWndMenu, CM_CONTINUOUS, FALSE );
456    }
457    else {
458        WinCheckMenuItem( hWndMenu, CM_SINGLEPAGE, FALSE );
459        WinCheckMenuItem( hWndMenu, CM_CONTINUOUS, TRUE );
460    }
461
462    docViewer->setPageLayout( layout );
463}
464
465
466bool Lucide::closeDocument( bool force )
467{
468    if ( doc != NULL ) {
469        if ( !docViewer->close( force ) && !force )
470            return false;
471        WinSendDlgItemMsg( hToolBar, TBID_PAGENUM, SPBM_SETLIMITS,
472                      MPFROMLONG( 0 ), MPFROMLONG( 0 ) );
473        delete doc;
474        doc = NULL;
475        WinSetWindowText( hWndFrame, title );
476        checkMenus( false );
477    }
478
479    if ( thumbnailData != NULL ) {
480        writeThumbnail( docFullName );
481        delete thumbnailData;
482        thumbnailData = NULL;
483        thumbnailDataLen = 0;
484    }
485
486    // clear the index
487    indexWin->clear( NULL );
488
489    return true;
490}
491
492void Lucide::loadthread( void* p)
493{
494    HAB thab = WinInitialize( 0 );
495    HMQ thmq = WinCreateMsgQueue( thab, 0 );
496
497    docLoaded = doc->loadFile( ev, docFullName, password, &loadErrorCode,
498                              &loadError );
499
500    //From FM2 valid.c 339
501    EASIZEBUF easize    = {0};
502    ULONG   ulDataLen   = sizeof(EASIZEBUF);
503    ULONG   ulParmLen   = 0;
504    CHAR szPath[4] = {0};
505
506    strncpy( szPath, docFullName, 3);
507    DosFSCtl(&easize, sizeof(EASIZEBUF), &ulDataLen, NULL, ulParmLen,
508             &ulParmLen, FSCTL_MAX_EASIZE, szPath, -1, FSCTL_PATHNAME);
509    //End FM2 code
510   
511    if ( !p && docLoaded && !password  && Thumbnail && easize.cbMaxEASize > 0 &&
512        doc->isCreateFileThumbnail( ev ) && isThumbNeeded( docFullName ) &&
513       doc->isScalable( ev )) {
514        loadProgressDlg->setText( getLocalizedString( MSGS_CREATING_THUMBNAIL ).c_str() );
515        if (!createThumbnail( doc ))
516        {
517            docLoaded = FALSE;
518        }
519    }
520    else if ( docLoaded && doc->getPageCount( ev ) > 0 ) {
521        double width = 0, height = 0;
522        doc->getPageSize( ev, 0, &width, &height );
523        if ( width <= 0.00001 || height <= 0.00001 )
524        {
525            docLoaded = FALSE;
526        }
527    }
528    else if (loadErrorCode != LU_LDERR_ENCRYPTED) // encrypted must loop to get password
529    {
530        docLoaded = FALSE;
531    }
532    if (!p) {
533    ULONG sz = sizeof( bool );
534    PrfQueryProfileData( hinilucideprofile, appName, "thumbnail", &Thumbnail, &sz );
535    loadProgressDlg->hide();
536    }
537
538    WinDestroyMsgQueue( thmq );
539    WinTerminate( thab );
540    _endthread();
541}
542
543void Lucide::loadDocument( const char *fn, bool saveme )
544{
545    // test if file supported and then close previous opened document
546    if ( pluginMan->createDocumentForFile( fn, true ) == NULL )
547    {
548        char *msg = newstrdupL( MSGS_NO_SUIT_PLUG );
549        WinMessageBox( HWND_DESKTOP, hWndFrame, msg,
550                       NULL, 0, MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE );
551        delete msg;
552    }
553    else
554    {
555        if ( !closeDocument() )
556            return;
557
558        doc = pluginMan->createDocumentForFile( fn, false );
559        if ( doc == NULL )
560        {
561            char *msg = newstrdupL( MSGS_NO_SUIT_PLUG );
562            WinMessageBox( HWND_DESKTOP, hWndFrame, msg,
563                           NULL, 0, MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE );
564            delete msg;
565        }
566        else
567        {
568            _fullpath( docFullName, fn, CCHMAXPATH );
569
570            if ( password != NULL ) {
571                delete password;
572                password = NULL;
573            }
574            bool once = true;
575            while ( once || ( password != NULL ) )
576            {
577                once = false;
578                docLoaded = false;
579                loadError = NULL;
580
581                // Load document asynchronously
582                if ( saveme ) {
583                    _beginthread( loadthread, NULL, 262144,(void *) 1 );
584                    DosSleep(10);
585                }
586                else {
587                    loadProgressDlg = new ProgressDlg( hWndFrame );
588                    char *ldmsg = newstrdupL( MSGS_LOADING_DOCUMENT );
589                    loadProgressDlg->setText( ldmsg );
590                    delete ldmsg;
591                    loadProgressDlg->show( loadthread, NULL ); // doc will be loaded
592                    delete loadProgressDlg;
593                }
594               
595
596                if ( password != NULL ) {
597                    delete password;
598                    password = NULL;
599                }
600                if ( docLoaded )
601                {
602                    char *t = new char[ 2048 ];
603                    char _dr[ _MAX_DRIVE ];
604                    char _di[ _MAX_DIR ];
605                    char _fn[ _MAX_FNAME ];
606                    char _ex[ _MAX_EXT ];
607                    _splitpath( docFullName, _dr, _di, _fn, _ex );
608                    strcpy( docDirName, _dr );
609                    strcat( docDirName, _di );
610                    strcpy( docFileName, _fn );
611                    strcat( docFileName, _ex );
612                    snprintf( t, 2048, "%s - %s", docFileName, title );
613                    WinSetWindowText( hWndFrame, t );
614                    delete t;
615                    recent->addFile( docFullName );
616                    setDocument( doc );
617                }
618                else
619                {
620                    if ( loadErrorCode == LU_LDERR_NO_ERROR )
621                    {
622                        char *m = newstrdupL( MSGS_FILE_LOAD_ERROR );
623                        WinMessageBox( HWND_DESKTOP, hWndFrame, m,
624                                      NULL, 0,
625                                      MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE );
626                        delete m;
627                    }
628                    else
629                    {
630                        std::string msgTempl = getLocalizedString( MSGS_LDERR );
631
632                        const int errmsgLen = 1024;
633                        char *errmsg = new char[ errmsgLen ];
634                        memset( errmsg, 0, errmsgLen );
635
636                        if ( loadErrorCode == LU_LDERR_CUSTOM )
637                        {
638                            snprintf( errmsg, errmsgLen, msgTempl.c_str(), loadError );
639                            SOMFree( loadError );
640                        }
641                        else
642                        {
643                            const char *lmsg = NULL;
644                            switch ( loadErrorCode )
645                            {
646                                case LU_LDERR_OUT_OF_MEMORY:
647                                    lmsg = MSGS_LDERR_OUT_OF_MEMORY;
648                                    break;
649                                case LU_LDERR_OPEN_ERROR:
650                                    lmsg = MSGS_LDERR_OPEN_ERROR;
651                                    break;
652                                case LU_LDERR_READ_ERROR:
653                                    lmsg = MSGS_LDERR_READ_ERROR;
654                                    break;
655                                case LU_LDERR_DAMAGED:
656                                    lmsg = MSGS_LDERR_DAMAGED;
657                                    break;
658                                case LU_LDERR_WRONG_FORMAT:
659                                    lmsg = MSGS_LDERR_WRONG_FORMAT;
660                                    break;
661                                case LU_LDERR_ENCRYPTED:
662                                    {
663                                        lmsg = MSGS_LDERR_ENCRYPTED;
664
665                                        PasswordDlg *pd = new PasswordDlg( hWndFrame );
666                                        if ( pd->showDialog() == DID_OK ) {
667                                            password = newstrdup( pd->getPassword() );
668                                        }
669                                        delete pd;
670                                    }
671                                    break;
672                            }
673
674                            if ( lmsg != NULL ) {
675                                snprintf( errmsg, errmsgLen, msgTempl.c_str(),
676                                          getLocalizedString( lmsg ).c_str() );
677                            }
678                        }
679
680                        if ( password == NULL )
681                        {
682                            WinMessageBox( HWND_DESKTOP, hWndFrame, errmsg, NULL, 0,
683                                           MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE );
684                        }
685                        delete[] errmsg;
686                    } // ( loadErrorCode == LU_LDERR_NO_ERROR )
687
688                    if ( doc && !password ) {
689                        delete doc;
690                        doc = NULL;
691                    }
692                } // ( docLoaded )
693            } // while ( once || ( password != NULL ) )
694        } // ( doc == NULL )
695    } // ( pluginMan->createDocumentForFile( fn, true ) == NULL )
696
697    loadFileList();
698}
699
700void Lucide::readMask( const char *mask )
701{
702    char *buf = new char[ CCHMAXPATH ];
703    strcpy( buf, docFullName );
704    char *r = buf + strlen( buf );
705    while ( r >= buf && *r != '\\' && *r != '/')
706        --r;
707    if ( r >= buf )
708    {
709        *( r + 1 ) = 0;
710        strcat( buf, mask );
711
712        find_t ffblk;
713        unsigned done = _dos_findfirst( buf, _A_RDONLY | _A_NORMAL, &ffblk );
714        while ( done == 0 )
715        {
716            fileList.push_back( find_t_name( ffblk ) );
717            done = _dos_findnext( &ffblk );
718        }
719        _dos_findclose( &ffblk );
720
721    }
722    delete[] buf;
723}
724
725// comparison, not case sensitive.
726bool compare_nocase( const std::string &first, const std::string &second)
727{
728    // note: stricmp is locale aware in kLIBC
729    return stricmp( first.c_str(), second.c_str() ) < 0;
730}
731
732void Lucide::loadFileList()
733{
734    fileList.clear();
735
736    char *exts = newstrdup( pluginMan->getExtsMask().c_str() );
737
738    char *p = strtok( exts, ";" );
739    while ( p != NULL )
740    {
741        readMask( p );
742        p = strtok( NULL, ";" );
743    }
744    delete exts;
745
746    std::sort( fileList.begin(), fileList.end(), compare_nocase );
747    fileListIterator = std::find( fileList.begin(), fileList.end(), docFileName );
748}
749
750void Lucide::openDocument()
751{
752    PFILEDLG fd = new FILEDLG;
753    memset( fd, 0, sizeof( FILEDLG ) );
754    fd->cbSize = sizeof( FILEDLG );
755    fd->fl = FDS_CENTER | FDS_OPEN_DIALOG;
756    PrfQueryProfileString( hinilucideprofile, appName, prfLvd, "",
757                           fd->szFullFile, sizeof( fd->szFullFile ) );
758    LcdFileDlg( HWND_DESKTOP, hWndFrame, fd );
759    if ( fd->lReturn == DID_OK )
760    {
761        char drv[ _MAX_DRIVE ] = "";
762        char dir[ _MAX_PATH ] = "";
763        char buf[ _MAX_PATH ] = "";
764        _splitpath( fd->szFullFile, drv, dir, NULL, NULL );
765        _makepath( buf, drv, dir, NULL, NULL );
766        PrfWriteProfileString( hinilucideprofile, appName, prfLvd, buf );
767
768        loadDocument( fd->szFullFile );
769    }
770    delete fd;
771}
772#if 1
773bool Lucide::saveDocument()
774{
775    bool saved = false;
776    bool loaded = false;
777    int buflen = 0;
778    short vposition;
779    short hposition;
780    double zoom;
781    long rotation;
782    long page;
783    char dirbuf[ CCHMAXPATH ];
784    char tempbuf[ CCHMAXPATH ];
785
786    if ( getenv( "TEMP" ))
787        strcpy(dirbuf,  getenv( "TEMP" ));
788    else if ( getenv( "TMP" ))
789        strcpy(dirbuf,  getenv( "TMP" ));
790    else if ( getenv( "TMPDIR" ))
791        strcpy(dirbuf,  getenv( "TMPDIR" ));
792    else
793    {
794        char *m = newstrdupL( MSGS_NO_TEMP_DIR_ERROR );
795        WinMessageBox( HWND_DESKTOP, hWndFrame, m, NULL,
796                       0, MB_OK | MB_ERROR | MB_MOVEABLE );
797        delete m;
798    }
799    buflen = strlen(dirbuf);
800    if ((dirbuf[buflen -1] != '\\') && (dirbuf[buflen -1] != '/') &&
801        (buflen < sizeof(dirbuf)))
802    {
803       strcat(dirbuf, "\\");
804    }
805
806    char fil[ _MAX_FNAME ] = "";
807    char ext[ _MAX_EXT ] = "";
808    _splitpath( docFullName, NULL, NULL, fil, ext );
809    strcat(dirbuf, fil);
810    strcat(dirbuf, ext);
811    strcpy(tempbuf, docFullName);
812    if (!(saved = doc->saveAs( ev, dirbuf )))
813    {
814        char *m = newstrdupL( MSGS_TEMP_FILE_SAVE_ERROR );
815        WinMessageBox( HWND_DESKTOP, hWndFrame, m, NULL,
816                       0, MB_OK | MB_ERROR | MB_MOVEABLE );
817        delete m;
818        return saved;
819    }
820    else
821    {
822        WinShowWindow(docViewer->getFrameHWND(), false);
823        WinShowWindow(docViewer->getViewHWND(), false);
824        docViewer->resetModifiedState();
825        rotation = docViewer->getRotation();
826        zoom = docViewer->getZoom();
827        vposition = docViewer->getVscrollPos();
828        hposition = docViewer->getHscrollPos();
829        page = docViewer->getCurrentPage();
830        loadDocument( dirbuf, true );
831    }
832    if (!( saved = doc->saveAs( ev, tempbuf ) ) )
833    {
834        char *m = newstrdupL( MSGS_FILE_SAVE_ERROR );
835        WinMessageBox( HWND_DESKTOP, hWndFrame, m, NULL,
836                       0, MB_OK | MB_ERROR | MB_MOVEABLE );
837        delete m;
838    }
839    else
840    {
841        loadDocument( tempbuf, true );
842        docViewer->setZoom( zoom );
843        docViewer->setRotation( rotation );
844        goToPage( page );
845        docViewer->vertScroll( docViewer->getViewHWND(),
846                              MPFROM2SHORT( vposition, SB_SLIDERPOSITION ) );
847        docViewer->horizScroll( docViewer->getViewHWND(),
848                               MPFROM2SHORT( hposition, SB_SLIDERPOSITION ) );
849    }
850    unlink( dirbuf );
851    docViewer->resetModifiedState();
852    WinShowWindow(docViewer->getFrameHWND(), true);
853    WinShowWindow(docViewer->getViewHWND(), true);
854    return saved;
855}
856#endif
857bool Lucide::saveDocumentAs()
858{
859    bool saved = false;
860    int buflen = 0;
861
862    char dirbuf[ CCHMAXPATH ];
863    PFILEDLG fd = new FILEDLG;
864    memset( fd, 0, sizeof( FILEDLG ) );
865    fd->cbSize = sizeof( FILEDLG );
866    fd->fl = FDS_CENTER | FDS_SAVEAS_DIALOG | FDS_ENABLEFILELB;
867    PrfQueryProfileString( hinilucideprofile, appName, prfLvd, "",
868                           dirbuf, sizeof( dirbuf ) );
869    // it may be possible that the trailing \ is missing, so add it
870    buflen = strlen(dirbuf);
871    if ((dirbuf[buflen -1] != '\\') && (dirbuf[buflen -1] != '/') && (buflen < sizeof(dirbuf)))
872    {
873       strcat(dirbuf, "\\");
874    }
875
876    char fil[ _MAX_FNAME ] = "";
877    char ext[ _MAX_EXT ] = "";
878    _splitpath( docFullName, NULL, NULL, fil, ext );
879    char filcopy[ _MAX_FNAME ] = "";
880    snprintf( filcopy, sizeof( filcopy ),
881              getLocalizedString( MSGS_FILE_COPY_SUFFIX ).c_str(), fil );
882    snprintf( fd->szFullFile, sizeof( fd->szFullFile ),
883              "%s%s%s", dirbuf, filcopy, ext );
884    WinFileDlg( HWND_DESKTOP, hWndFrame, fd );
885    if ( fd->lReturn == DID_OK )
886    {
887        bool doSave = true;
888        if ( access( fd->szFullFile, F_OK ) == 0 )
889        {
890            char *t = newstrdupL( MSGS_WARNING );
891            char *m = newstrdupL( MSGS_OVERWRITE_FILE );
892            ULONG response = WinMessageBox( HWND_DESKTOP, hWndFrame, m, t,
893                                            0, MB_YESNO | MB_WARNING | MB_MOVEABLE );
894            delete m;
895            delete t;
896
897            doSave = ( response == MBID_YES );
898        }
899
900        if ( doSave )
901        {
902            // @todo poppler has troubles saving to the same file name
903            // (some locking issues) so forbid it for now
904
905           // we need to normalise the path
906           strcpy(dirbuf, docFullName);
907           for(buflen = 0; buflen < strlen(dirbuf); ++buflen)
908           {
909               if (dirbuf[buflen] == '/')
910               {
911                   dirbuf[buflen] = '\\';
912               }
913           }
914
915            if ( ( saved = false, stricmp( dirbuf, fd->szFullFile ) == 0 ) ||
916                 !( saved = doc->saveAs( ev, fd->szFullFile ) ) )
917            {
918                char *m = newstrdupL( MSGS_FILE_SAVE_ERROR );
919                WinMessageBox( HWND_DESKTOP, hWndFrame, m, NULL,
920                               0, MB_OK | MB_ERROR | MB_MOVEABLE );
921                delete m;
922            }
923            else
924            {
925                if ( stricmp( docFullName, fd->szFullFile ) != 0 )
926                    recent->addFile( fd->szFullFile );
927                docViewer->resetModifiedState();
928            }
929        }
930    }
931    delete fd;
932    return saved;
933}
934
935void Lucide::checkNavpane()
936{
937    if ( Lucide::showIndex ) {
938        WinCheckMenuItem( hWndMenu, CM_NAVPANE, TRUE );
939        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_NAVPANE ), (MPARAM)TRUE );
940    }
941    else {
942        WinCheckMenuItem( hWndMenu, CM_NAVPANE, FALSE );
943        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_NAVPANE ), (MPARAM)FALSE );
944    }
945}
946
947
948void Lucide::toggleFullscreenEx( bool presentation, bool atStartup )
949{
950    enum TriState { NoChange, On, Off };
951    TriState fullscreenState = NoChange;
952    TriState presentationState = NoChange;
953
954    if ( !presentation )
955    {
956        // fullscreen command issued
957        if ( !isFullscreen )
958        {
959            if ( isPresentation ) {
960                presentationState = Off;
961                isPresentation = false;
962            } else {
963                fullscreenState = On;
964            }
965            isFullscreen = true;
966        }
967        else
968        {
969            if ( isPresentation ) {
970                presentationState = Off;
971                isPresentation = false;
972            } else {
973                fullscreenState = Off;
974                isFullscreen = false;
975            }
976        }
977    }
978    else
979    {
980        // presentation command issued
981        if ( !isPresentation )
982        {
983            presentationState = On;
984            if ( !isFullscreen )
985                fullscreenState = On;
986        }
987        else
988        {
989            presentationState = Off;
990            if ( !isFullscreen )
991                fullscreenState = Off;
992        }
993
994        isPresentation = !isPresentation;
995    }
996
997    ULONG ulFrameStyle = WinQueryWindowULong( hWndFrame, QWL_STYLE );
998
999    if ( presentationState == Off )
1000    {
1001        docViewer->setPresentation( false );
1002        WinSetParent( hWndMenu, hWndFrame, FALSE );
1003    }
1004    else if ( presentationState == On )
1005    {
1006        docViewer->setPresentation( true );
1007        WinSetParent( hWndMenu, HWND_OBJECT, FALSE );
1008    }
1009
1010    if ( fullscreenState == Off )
1011    {
1012        WinSetParent( hFrameSysmenu,  hWndFrame, FALSE );
1013        WinSetParent( hFrameTitlebar, hWndFrame, FALSE );
1014        WinSetParent( hFrameMinMax,   hWndFrame, FALSE );
1015        ulFrameStyle |= FS_SIZEBORDER;
1016
1017        // PM does not synchronize the title bar hilite state when it is added
1018        // to the frame window. Do it ourselves
1019        BOOL active = WinQueryActiveWindow( HWND_DESKTOP ) == hWndFrame;
1020        WinSendMsg( hFrameTitlebar, TBM_SETHILITE,
1021                    MPFROMSHORT( active ), MPVOID );
1022
1023        // reset the fullscreen menu check
1024        WinCheckMenuItem( hWndMenu, CM_FULLSCREEN, FALSE );
1025        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_FULLSCREEN ), (MPARAM)FALSE );
1026
1027    }
1028    else if ( fullscreenState == On )
1029    {
1030        if ( !atStartup )
1031        {
1032            WinQueryWindowPos( hWndFrame, &winPos.Swp );
1033            winPos.XRestore  = WinQueryWindowUShort( hWndFrame, QWS_XRESTORE );
1034            winPos.YRestore  = WinQueryWindowUShort( hWndFrame, QWS_YRESTORE );
1035            winPos.CXRestore = WinQueryWindowUShort( hWndFrame, QWS_CXRESTORE );
1036            winPos.CYRestore = WinQueryWindowUShort( hWndFrame, QWS_CYRESTORE );
1037            winPos.XMinimize = WinQueryWindowUShort( hWndFrame, QWS_XMINIMIZE );
1038            winPos.YMinimize = WinQueryWindowUShort( hWndFrame, QWS_YMINIMIZE );
1039        }
1040
1041        // set the fullscreen menu check
1042        WinCheckMenuItem( hWndMenu, CM_FULLSCREEN, TRUE );
1043        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_FULLSCREEN ), (MPARAM)TRUE );
1044
1045        WinSetParent( hFrameSysmenu,  HWND_OBJECT, FALSE );
1046        WinSetParent( hFrameTitlebar, HWND_OBJECT, FALSE );
1047        WinSetParent( hFrameMinMax,   HWND_OBJECT, FALSE );
1048        ulFrameStyle &= ~FS_SIZEBORDER;
1049    }
1050
1051    if ( fullscreenState != NoChange || presentationState != NoChange )
1052    {
1053        WinSetWindowULong( hWndFrame, QWL_STYLE, ulFrameStyle );
1054        WinSendMsg( hWndFrame, WM_UPDATEFRAME, MPVOID, MPVOID );
1055    }
1056
1057    if ( presentationState == Off )
1058    {
1059        WinSendMsg( hVertSplitter, SBM_SETSPLITTERSIZE, MPFROMSHORT( -1 ), MPVOID );
1060        WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS,
1061                    MPFROMSHORT( Lucide::showIndex ? Lucide::splitterPos : 0 ), MPVOID );
1062        WinSendMsg( hHorizSplitter, SBM_SETFIXEDSIZE,
1063            MPFROMSHORT( DEFAULT_PICTSIZE + TOOLBAR_HEIGHT_ADD ), MPVOID );
1064
1065        // reset the presentation menu check
1066        WinCheckMenuItem( hWndMenu, CM_PRESENTATION, FALSE );
1067        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_PRESENTATION ), (MPARAM)FALSE );
1068
1069    }
1070    else if ( presentationState == On )
1071    {
1072        WinSendMsg( hHorizSplitter, SBM_SETSPLITTERPOS, 0, MPVOID );
1073        WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS, 0, MPVOID );
1074        WinSendMsg( hVertSplitter, SBM_SETSPLITTERSIZE, 0, MPVOID );
1075
1076        // set the presentation menu check
1077        WinCheckMenuItem( hWndMenu, CM_PRESENTATION, TRUE );
1078        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_PRESENTATION ), (MPARAM)TRUE );
1079    }
1080
1081    if ( fullscreenState == Off )
1082    {
1083        WinSetWindowUShort( hWndFrame, QWS_XRESTORE,  winPos.XRestore );
1084        WinSetWindowUShort( hWndFrame, QWS_YRESTORE,  winPos.YRestore );
1085        WinSetWindowUShort( hWndFrame, QWS_CXRESTORE, winPos.CXRestore );
1086        WinSetWindowUShort( hWndFrame, QWS_CYRESTORE, winPos.CYRestore );
1087        WinSetWindowUShort( hWndFrame, QWS_XMINIMIZE, winPos.XMinimize );
1088        WinSetWindowUShort( hWndFrame, QWS_YMINIMIZE, winPos.YMinimize );
1089        WinSetWindowPos( hWndFrame, NULLHANDLE,
1090                         winPos.Swp.x, winPos.Swp.y, winPos.Swp.cx, winPos.Swp.cy,
1091                         SWP_SIZE | SWP_MOVE | SWP_SHOW );
1092    }
1093    else if ( fullscreenState == On )
1094    {
1095        WinSetWindowPos( hWndFrame, NULLHANDLE, 0, 0,
1096                         WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ),
1097                         WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ),
1098                         SWP_SIZE | SWP_MOVE | SWP_SHOW );
1099    }
1100}
1101
1102
1103void Lucide::focusDocview()
1104{
1105    WinSetFocus( HWND_DESKTOP, docViewer->getViewHWND() );
1106}
1107
1108void Lucide::focusIndex()
1109{
1110    WinSetFocus( HWND_DESKTOP, indexWin->getIndexHWND() );
1111}
1112
1113void Lucide::cmdSwitchWindow()
1114{
1115    if ( activeWindow == AwIndex ) {
1116        focusDocview();
1117    } else {
1118        focusIndex();
1119    }
1120}
1121
1122void Lucide::toggleZoom()
1123{
1124    if ( ( doc != NULL ) && doc->isScalable( ev ) )
1125    {
1126        bool isZoom = !docViewer->isZoomMode();
1127        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_ZOOM_IN_OUT ), (MPARAM)isZoom );
1128        docViewer->setZoomMode( isZoom );
1129    }
1130}
1131
1132void Lucide::cmdMinimize()
1133{
1134    if ( isFullscreen ) {
1135        toggleFullscreen();
1136    }
1137    WinSetWindowPos( hWndFrame, HWND_TOP, 0, 0, 0, 0, SWP_MINIMIZE );
1138}
1139
1140void Lucide::cmdSwitchToPresentation()
1141{
1142    if ( !isPresentation )
1143    {
1144        SWP pos = {0};
1145        WinQueryWindowPos( hWndFrame, &pos );
1146
1147        if ( pos.fl & SWP_MINIMIZE ) {
1148            WinSetWindowPos( hWndFrame, HWND_TOP, 0, 0, 0, 0,
1149                    SWP_SHOW | SWP_ACTIVATE | SWP_RESTORE | SWP_ZORDER );
1150        }
1151        togglePresentation();
1152    }
1153}
1154
1155void Lucide::newWindow( char *file, bool addDir )
1156{
1157    char *param = NULL;
1158
1159    if ( file != NULL )
1160    {
1161        if ( addDir )
1162        {
1163            param = new char[ CCHMAXPATH ];
1164            strcpy( param, docFullName );
1165            char *lastSlash = strrchr( param, '\\' );
1166            if ( lastSlash != NULL ) {
1167                *( lastSlash + 1 ) = 0;
1168            }
1169            strcat( param, file );
1170        }
1171        else {
1172            param = newstrdup( file );
1173        }
1174    }
1175
1176#if defined(__WATCOM__)
1177    const char *execname = __argv[0];
1178#else
1179    char execname[ _MAX_PATH ];
1180    _execname( execname, sizeof(execname) );
1181#endif
1182
1183    PROGDETAILS pd;
1184    pd.Length                      = sizeof( PROGDETAILS );
1185    pd.progt.progc                 = PROG_DEFAULT;
1186    pd.progt.fbVisible             = SHE_VISIBLE;
1187    pd.pszTitle                    = NULL;
1188    pd.pszExecutable               = execname;
1189    pd.pszParameters               = NULL;
1190    pd.pszStartupDir               = NULL;
1191    pd.pszIcon                     = NULL;
1192    pd.pszEnvironment              = NULL;
1193    pd.swpInitial.fl               = SWP_ACTIVATE;
1194    pd.swpInitial.cy               = 0;
1195    pd.swpInitial.cx               = 0;
1196    pd.swpInitial.y                = 0;
1197    pd.swpInitial.x                = 0;
1198    pd.swpInitial.hwndInsertBehind = HWND_TOP;
1199    pd.swpInitial.hwnd             = NULLHANDLE;
1200    pd.swpInitial.ulReserved1      = 0;
1201    pd.swpInitial.ulReserved2      = 0;
1202
1203    WinStartApp( NULLHANDLE, &pd, param, NULL, 0 );
1204
1205    delete[] param;
1206}
1207
1208void Lucide::gotoFile( FileList file )
1209{
1210    if ( fileList.size() == 0 ) {
1211        return;
1212    }
1213
1214    if ( fileListIterator == fileList.end() ) {
1215        // If viewed file extension not in supported extensions
1216        //   list - fileListIterator will equal fileList.end()
1217        fileListIterator = fileList.begin();
1218    }
1219
1220    if ( file == ListFirst ) {
1221        fileListIterator = fileList.begin();
1222    }
1223    else if ( file == ListPrevious )
1224    {
1225        if ( fileListIterator == fileList.begin() ) {
1226            fileListIterator = fileList.end();
1227        }
1228        fileListIterator--;
1229    }
1230    else if ( file == ListNext )
1231    {
1232        fileListIterator++;
1233        if ( fileListIterator == fileList.end() ) {
1234            fileListIterator = fileList.begin();
1235        }
1236    }
1237    else if ( file == ListLast ) {
1238        fileListIterator = fileList.end();
1239        fileListIterator--;
1240    }
1241
1242    std::string fname = *fileListIterator;
1243    char *fn = new char[ CCHMAXPATH ];
1244    strcpy( fn, docDirName );
1245    strcat( fn, fname.c_str() );
1246
1247    loadDocument( fn );
1248    delete[] fn;
1249}
1250/*
1251 * open Profile loads Lucide.ini and moves the ini entries from OS2.ini to itself.
1252 * The ini entries in luutils.cpp and stbrowser.c should remain in OS2.ini
1253 */
1254void Lucide::openProfile()
1255{
1256    char filename[CCHMAXPATH];
1257    ULONG sz = sizeof( filename );
1258
1259    if (PrfQueryProfileString( HINI_USERPROFILE, appName, "Path", "", filename, sz ))
1260        strcat( strupr(filename), "\\LUCIDE.INI" );
1261    else
1262        strcpy( filename, "LUCIDE.INI" );
1263    hinilucideprofile = PrfOpenProfile(hab, filename);
1264
1265    bool converted = FALSE;
1266    sz = sizeof( bool );
1267    PrfQueryProfileData(hinilucideprofile, appName, "convertedINI", &converted, &sz );
1268   
1269    if ( !converted ) {
1270        sz = sizeof( bool );
1271        PrfQueryProfileData( HINI_USERPROFILE, appName, "thumbnail", &Thumbnail, &sz );
1272        sz = sizeof( bool );
1273        PrfWriteProfileData( hinilucideprofile, appName, "thumbnail", &Thumbnail, sz );
1274        sz = sizeof( bool );
1275        PrfWriteProfileData( HINI_USERPROFILE, appName, "thumbnail", NULL, sz );
1276        sz = sizeof( filename );
1277        PrfQueryProfileString( HINI_USERPROFILE, appName, prfLvd, "", filename, sz );
1278        PrfWriteProfileString( hinilucideprofile, appName,  prfLvd, filename );
1279        PrfWriteProfileString( HINI_USERPROFILE, appName,  prfLvd, NULL );
1280        char valbuf[ 3 ] = "";
1281        PrfQueryProfileInt( HINI_USERPROFILE, appName, prfSplpos, Lucide::splitterPos );
1282        PrfWriteProfileString( hinilucideprofile, appName, prfSplpos,
1283                              itoa( Lucide::splitterPos, valbuf, 10 ) );
1284        PrfWriteProfileString( HINI_USERPROFILE, appName, prfSplpos, NULL );
1285        PrfQueryProfileInt( HINI_USERPROFILE, appName, prfShowind, Lucide::showIndex );
1286        PrfWriteProfileString( hinilucideprofile, appName, prfShowind,
1287                              itoa( Lucide::showIndex, valbuf, 10 ) );
1288        PrfWriteProfileString( HINI_USERPROFILE, appName, prfShowind, NULL );
1289        if ( PrfQueryProfileInt( HINI_USERPROFILE, appName, prfFullscreen, 0 ) == 1) {
1290            PrfWriteProfileString( hinilucideprofile, appName, prfFullscreen, "1" );
1291            PrfWriteProfileString( HINI_USERPROFILE, appName, prfFullscreen, NULL );
1292        }
1293        if (PrfQueryProfileInt( HINI_USERPROFILE, appName, prfPresentation, 0 ) == 1) {
1294            PrfWriteProfileString( hinilucideprofile, appName, prfPresentation, "1" );
1295            PrfWriteProfileString( HINI_USERPROFILE, appName, prfPresentation, NULL );
1296        }
1297        double   zoom;
1298        sz = sizeof( zoom );
1299        PrfQueryProfileData( HINI_USERPROFILE, appName, "Zoom", &zoom, &sz );
1300        sz = sizeof( zoom );
1301        PrfWriteProfileData( hinilucideprofile, appName, "Zoom", &zoom, sz );
1302        sz = sizeof( zoom );
1303        PrfWriteProfileData( HINI_USERPROFILE, appName, "Zoom", NULL, sz );
1304        PgLayout layout;
1305        char buff[ 10 ];
1306        PrfQueryProfileInt( HINI_USERPROFILE, appName, "Layout", layout );
1307        PrfWriteProfileString( hinilucideprofile, appName, "Layout", itoa( layout, buff, 10 ) );
1308        PrfWriteProfileString( HINI_USERPROFILE, appName, "Layout", NULL );
1309        int buttonctl = 0;
1310        buttonctl = PrfQueryProfileInt(HINI_USERPROFILE, appName, "useAsImage", buttonctl);
1311        PrfWriteProfileString(hinilucideprofile, appName, "useAsImage",
1312                              itoa(buttonctl, buff, 10));
1313        PrfWriteProfileString(HINI_USERPROFILE, appName, "useAsImage", NULL );
1314        buttonctl = 0;
1315        buttonctl = PrfQueryProfileInt(HINI_USERPROFILE, appName, "useHigherImageQuality", buttonctl);
1316        PrfWriteProfileString(hinilucideprofile, appName, "useHigherImageQuality",
1317                              itoa(buttonctl, buff, 10));
1318        PrfWriteProfileString(HINI_USERPROFILE, appName, "useHigherImageQuality",NULL );
1319        buttonctl = 0;
1320        buttonctl = PrfQueryProfileInt(HINI_USERPROFILE, appName, "IgnMargins", buttonctl);
1321        PrfWriteProfileString(hinilucideprofile, appName, "IgnMargins",
1322                              itoa(buttonctl, buff, 10));
1323        PrfWriteProfileString(HINI_USERPROFILE, appName, "IgnMargins", NULL);
1324        buttonctl = 0;
1325        buttonctl = PrfQueryProfileInt(HINI_USERPROFILE, appName, "PageRange", buttonctl);
1326        PrfWriteProfileString(hinilucideprofile, appName, "PageRange",
1327                              itoa(buttonctl, buff, 10));
1328        PrfWriteProfileString(HINI_USERPROFILE, appName, "PageRange", NULL);
1329        int bufsize = ( CCHMAXPATH * RECENT_SIZE ) + RECENT_SIZE + 2;
1330        char *buf = new char[ bufsize ];
1331        memset( buf, 0, bufsize );
1332        PrfQueryProfileString( HINI_USERPROFILE, appName, "RecentFiles", "", buf, bufsize );
1333        PrfWriteProfileString( hinilucideprofile, appName, "RecentFiles", buf );
1334        PrfWriteProfileString( HINI_USERPROFILE, appName, "RecentFiles", NULL );
1335        converted = TRUE;
1336        sz = sizeof( bool );
1337        PrfWriteProfileData( hinilucideprofile, appName, "convertedINI", &converted, sz );
1338    }
1339}
1340
1341void Lucide::savePosition()
1342{
1343    if ( !WinIsWindow( hab, hWndFrame ) )
1344        return;
1345
1346    char valbuf[ 3 ] = "";
1347    PrfWriteProfileString( hinilucideprofile, appName, prfSplpos,
1348                           itoa( Lucide::splitterPos, valbuf, 10 ) );
1349    PrfWriteProfileString( hinilucideprofile, appName, prfShowind,
1350                           itoa( Lucide::showIndex, valbuf, 10 ) );
1351
1352    if ( isFullscreen )
1353        PrfWriteProfileString( hinilucideprofile, appName, prfFullscreen, "1" );
1354    else
1355        PrfWriteProfileString( hinilucideprofile, appName, prfFullscreen, NULL );
1356
1357    if ( isPresentation )
1358        PrfWriteProfileString( hinilucideprofile, appName, prfPresentation, "1" );
1359    else
1360        PrfWriteProfileString( hinilucideprofile, appName, prfPresentation, NULL );
1361
1362    if ( !isFullscreen && !isPresentation ) {
1363        WinQueryWindowPos( hWndFrame, &winPos.Swp );
1364        winPos.XRestore  = WinQueryWindowUShort( hWndFrame, QWS_XRESTORE );
1365        winPos.YRestore  = WinQueryWindowUShort( hWndFrame, QWS_YRESTORE );
1366        winPos.CXRestore = WinQueryWindowUShort( hWndFrame, QWS_CXRESTORE );
1367        winPos.CYRestore = WinQueryWindowUShort( hWndFrame, QWS_CYRESTORE );
1368        winPos.XMinimize = WinQueryWindowUShort( hWndFrame, QWS_XMINIMIZE );
1369        winPos.YMinimize = WinQueryWindowUShort( hWndFrame, QWS_YMINIMIZE );
1370    }
1371
1372    PrfWriteProfileData( HINI_USERPROFILE, appName, prfFwp, &winPos, sizeof( winPos ) );
1373}
1374
1375void Lucide::restorePosition()
1376{
1377    splitterPos = PrfQueryProfileInt( hinilucideprofile, appName, prfSplpos,
1378                                      Lucide::splitterPos );
1379    showIndex = PrfQueryProfileInt( hinilucideprofile, appName, prfShowind,
1380                                    Lucide::showIndex );
1381
1382    WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS,
1383                MPFROMSHORT( showIndex ? splitterPos : 0 ), MPVOID );
1384
1385    bool fullscreen = PrfQueryProfileInt( hinilucideprofile, appName,
1386                                          prfFullscreen, 0 ) == 1;
1387    bool presentation = PrfQueryProfileInt( hinilucideprofile, appName,
1388                                            prfPresentation, 0 ) == 1;
1389
1390    LONG sx, sy;
1391    sx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
1392    sy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
1393
1394    ULONG SwpOptions = SWP_MOVE | SWP_SIZE | SWP_ACTIVATE | SWP_SHOW;
1395    bool atStartup = true;
1396
1397    ULONG ulWpSize = sizeof( winPos );
1398    if ( PrfQueryProfileData( HINI_USERPROFILE, appName, prfFwp, &winPos, &ulWpSize ) )
1399    {
1400        if ( winPos.Swp.fl & SWP_MAXIMIZE ) {
1401            SwpOptions |= SWP_MAXIMIZE;
1402        }
1403        else if ( winPos.Swp.fl & SWP_MINIMIZE ) {
1404            SwpOptions |= SWP_MINIMIZE;
1405        }
1406
1407        LONG sx, sy;
1408        sx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
1409        sy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
1410
1411        if ( winPos.Swp.x > sx ) {
1412            winPos.Swp.x = sx - winPos.Swp.cx;
1413        }
1414        if ( winPos.Swp.y > sy ) {
1415            winPos.Swp.y = sy - winPos.Swp.cy;
1416        }
1417
1418        // Just a note: the FID_CLIENT window is only resized by WinSetWindowPos()
1419        // on the frame if the size is actually changed *and* the SWP_SHOW flag
1420        // is present (PM bug?). Therefore, when the saved normal size the same
1421        // as fullscreen and we should go fullscreen at startup, WinSetWindowPos()
1422        // issued from toggleFullscreenEx() will not resize FID_CLIENT even
1423        // though it will contain SWP_SHOW
1424
1425        if ( !fullscreen && !presentation ) {
1426            // only set the normal size if no if fullscreen or presentation is
1427            // requested, to avoid flicker. We could also avoid flicker by
1428            // omitting SWP_SHOW but see the note above
1429            WinSetWindowPos( hWndFrame, NULLHANDLE,
1430                             winPos.Swp.x, winPos.Swp.y, winPos.Swp.cx, winPos.Swp.cy,
1431                             SwpOptions );
1432        }
1433
1434        WinSetWindowUShort( hWndFrame, QWS_XRESTORE,  winPos.XRestore );
1435        WinSetWindowUShort( hWndFrame, QWS_YRESTORE,  winPos.YRestore );
1436        WinSetWindowUShort( hWndFrame, QWS_CXRESTORE, winPos.CXRestore );
1437        WinSetWindowUShort( hWndFrame, QWS_CYRESTORE, winPos.CYRestore );
1438        WinSetWindowUShort( hWndFrame, QWS_XMINIMIZE, winPos.XMinimize );
1439        WinSetWindowUShort( hWndFrame, QWS_YMINIMIZE, winPos.YMinimize );
1440
1441        // we don't the app to be minimized at startup
1442        if ( SwpOptions & SWP_MINIMIZE )
1443            WinSetWindowPos( hWndFrame, NULLHANDLE, 0, 0, 0, 0, SWP_RESTORE );
1444    }
1445    else
1446    {
1447        typedef
1448        BOOL ( APIENTRY *WinQueryDesktopWorkArea_T ) ( HWND hwndDesktop,
1449                                                       PRECTL pwrcWorkArea );
1450        static WinQueryDesktopWorkArea_T WinQueryDesktopWorkArea =
1451            (WinQueryDesktopWorkArea_T) ~0;
1452
1453        if ( (ULONG) WinQueryDesktopWorkArea == (ULONG) ~0 ) {
1454            if ( my_DosQueryProcAddr( "PMMERGE", 5469,
1455                                      (PFN *) &WinQueryDesktopWorkArea ) )
1456                WinQueryDesktopWorkArea = NULL;
1457        }
1458
1459        SWP swp;
1460        RECTL rcl;
1461        if ( WinQueryDesktopWorkArea &&
1462             WinQueryDesktopWorkArea( HWND_DESKTOP, &rcl ) ) {
1463            swp.x = rcl.xLeft;
1464            swp.y = rcl.yBottom;
1465            swp.cx = rcl.xRight - rcl.xLeft;
1466            swp.cy = rcl.yTop - rcl.yBottom;
1467        } else {
1468            swp.x = 0;
1469            swp.y = 0;
1470            swp.cx = sx;
1471            swp.cy = sy;
1472        }
1473
1474        swp.x += 16;
1475        swp.y += 16;
1476        swp.cx -= 32;
1477        swp.cy -= 32;
1478
1479        WinSetWindowPos( hWndFrame, NULLHANDLE, swp.x, swp.y, swp.cx, swp.cy,
1480                         SwpOptions );
1481
1482        // we don't initialize winPos here so reset atStartup to let
1483        // toggleFullscreenEx() do this
1484        atStartup = false;
1485    }
1486
1487    if ( fullscreen )
1488    {
1489        toggleFullscreenEx( false, atStartup );
1490        isFullscreen = fullscreen;
1491    }
1492    else if ( presentation )
1493    {
1494        toggleFullscreenEx( true, atStartup );
1495    }
1496}
1497
1498static bool isAncestorOf( HWND hwnd1, HWND hwnd2 )
1499{
1500    static HWND desktop = NULLHANDLE;
1501    if ( desktop == NULLHANDLE )
1502        desktop = WinQueryDesktopWindow( hab, NULLHANDLE );
1503
1504    if ( hwnd1 == NULLHANDLE || hwnd2 == NULLHANDLE )
1505        return false;
1506
1507    while ( hwnd2 != hwnd1 && hwnd2 != desktop )
1508        hwnd2 = WinQueryWindow( hwnd2, QW_PARENT );
1509
1510    return hwnd2 == hwnd1;
1511}
1512
1513static MRESULT EXPENTRY frameProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
1514{
1515    switch ( msg )
1516    {
1517        case WM_TRANSLATEACCEL:
1518        {
1519            // change the accel logic by first letting the focus window process
1520            // WM_CHAR and only translate it to accel if not handled (this makes
1521            // sure that standard keyboard shortcuts in e.g. input fields work
1522            // even if we define our own accelerators from these shortcuts in
1523            // the main window). Make an exception for VK_TAB since it's always
1524            // eaten by the standard window procedure and therefore the accel
1525            // table will never be called. Note that we do this trick only for
1526            // the document window and its children: other windows such as the
1527            // standard frame controls like menu etc. are known to demonstrate
1528            // weird behavior (for example, the menu window seems to exit the
1529            // menu mode on any WM_CHAR sent to it)
1530            HWND focus = WinQueryFocus( HWND_DESKTOP );
1531            if ( !isAncestorOf( docViewer->getFrameHWND(), focus ) )
1532                break;
1533            PQMSG pqmsg = (PQMSG)mp1;
1534            if ( pqmsg->msg != WM_CHAR )
1535                break;
1536            if ( !( SHORT1FROMMP( pqmsg->mp1 ) & KC_VIRTUALKEY ) ||
1537                 !( SHORT2FROMMP( pqmsg->mp2 ) == VK_TAB ) )
1538            {
1539                if ( focus == pqmsg->hwnd && focus != hwnd ) {
1540                    if ( WinDispatchMsg( hab, pqmsg ) ) {
1541                        pqmsg->msg = WM_NULL;
1542                        return (MRESULT)TRUE;
1543                    }
1544                }
1545            }
1546            // in presentation mode, we hide the menu which effectively makes
1547            // all disabled items work through accelerators which is completely
1548            // unexpected. Fix it by translating accels manually and checking
1549            // if they are disabled in the hidden menu
1550            BOOL ok = WinTranslateAccel( hab, hwnd,
1551                                         WinQueryAccelTable( hab, hwnd ),
1552                                         pqmsg );
1553            // try the menu mnemonics if no explicit accels found
1554            if ( !ok )
1555                ok = (BOOL)WinSendMsg( hwnd, 0x0195 /*WM_TRANSLATEMNEMONIC*/,
1556                                       MPFROMP( pqmsg ), NULL );
1557            if ( ok )
1558            {
1559                if ( pqmsg->msg == WM_COMMAND ) {
1560                    SHORT cm = SHORT1FROMMP(pqmsg->mp1);
1561                    if ( !WinIsMenuItemEnabled( hWndMenu, cm ) )
1562                        pqmsg->msg = WM_NULL;
1563                }
1564                return (MRESULT)TRUE;
1565            }
1566            return (MRESULT)FALSE;
1567        }
1568
1569        case WM_SYSCOMMAND:
1570        {
1571            if ( SHORT1FROMMP(mp1) == SC_CLOSE ) {
1572                // the system menu is disabled in fullscreen/presentation mode
1573                // but we still want to exit with Alt-F4 so always handle it here
1574                WinPostMsg( hWndFrame, WM_CLOSE, NULL, NULL );
1575                return (MRESULT)FALSE;
1576            }
1577        }
1578        break;
1579    }
1580
1581    return pOldFrameProc( hwnd, msg, mp1, mp2 );
1582}
1583
1584static MRESULT EXPENTRY splProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
1585{
1586    switch ( msg )
1587    {
1588        case WM_CONTROL:
1589        {
1590            if ( ( SHORT1FROMMP( mp1 ) == ID_SPLITTER ) &&
1591                 ( SHORT2FROMMP( mp1 ) == SBN_POSITIONCHANGED ) )
1592            {
1593                SHORT pos = SHORT1FROMMP( mp2 );
1594                if ( pos > 0 ) {
1595                    Lucide::splitterPos = pos;
1596                    Lucide::showIndex = true;
1597                }
1598                else {
1599                    Lucide::showIndex = false;
1600                }
1601                Lucide::checkNavpane();
1602            }
1603        }
1604        break;
1605
1606        case WM_COMMAND:
1607        {
1608            switch ( SHORT1FROMMP(mp1) )
1609            {
1610                case CM_NEW_WINDOW:
1611                    Lucide::newWindow( NULL, false );
1612                    return (MRESULT)FALSE;
1613
1614                case CM_OPEN:
1615                    Lucide::openDocument();
1616                    return (MRESULT)FALSE;
1617
1618                case CM_FILEFIRST:
1619                    Lucide::gotoFile( ListFirst );
1620                    return (MRESULT)FALSE;
1621
1622                case CM_FILEPREVIOUS:
1623                    Lucide::gotoFile( ListPrevious );
1624                    return (MRESULT)FALSE;
1625
1626                case CM_FILENEXT:
1627                    Lucide::gotoFile( ListNext );
1628                    return (MRESULT)FALSE;
1629
1630                case CM_FILELAST:
1631                    Lucide::gotoFile( ListLast );
1632                    return (MRESULT)FALSE;
1633
1634                case CM_RECENT + 1:
1635                case CM_RECENT + 2:
1636                case CM_RECENT + 3:
1637                case CM_RECENT + 4:
1638                case CM_RECENT + 5:
1639                case CM_RECENT + 6:
1640                case CM_RECENT + 7:
1641                case CM_RECENT + 8:
1642                case CM_RECENT + 9:
1643                {
1644                    std::string f = recent->getFile( SHORT1FROMMP(mp1) );
1645                    Lucide::loadDocument( f.c_str() );
1646                    return (MRESULT)FALSE;
1647                }
1648
1649                case CM_RECENTCLEAR:
1650                    recent->clear();
1651                    return (MRESULT)FALSE;
1652
1653                case CM_BACK:
1654                case CM_BACKNAV:
1655                    docViewer->goToPage(docViewer->getPreviousPage());
1656                    docViewer->unsetPreviousPage();
1657                    Lucide::checkMenus( false );
1658                    Lucide::checkNavigationMenus();
1659                    return (MRESULT)FALSE;
1660
1661                case CM_SAVEAS:
1662                    Lucide::saveDocumentAs();
1663                    return (MRESULT)FALSE;
1664
1665                case CM_SAVE:
1666                    Lucide::saveDocument();
1667                    return (MRESULT)FALSE;
1668
1669                case CM_CLOSE:
1670                    Lucide::closeDocument();
1671                    return (MRESULT)FALSE;
1672
1673                case CM_PRINT:
1674                {
1675                    PrintDlg *d = new PrintDlg( hWndFrame, doc, Lucide::docFileName,
1676                                                docViewer->getCurrentPage() + 1 );
1677                    if ( d->showDialog() == DID_OK )
1678                    {
1679                        // print
1680                        PrintSetup *p = new PrintSetup;
1681                        memset( p, 0, sizeof( PrintSetup ) );
1682                        d->getPrintSetup( p );
1683                        printDocument( hWndFrame, doc, Lucide::docFileName, p );
1684                        delete p;
1685                    }
1686                    delete d;
1687                    return (MRESULT)FALSE;
1688                }
1689
1690                case CM_EXIT:
1691                    WinPostMsg( hWndFrame, WM_CLOSE, NULL, NULL );
1692                    return (MRESULT)FALSE;
1693
1694                case CM_DOCINFO:
1695                {
1696                    LuDocumentInfo *dinfo = doc->getDocumentInfo( ev );
1697                    DocInfoDlg *d = new DocInfoDlg( hWndFrame, dinfo, Lucide::docFileName );
1698                    d->doDialog();
1699                    LuDocument::freeDocumentInfo( ev, dinfo );
1700                    return (MRESULT)FALSE;
1701                }
1702
1703                case CM_FONTSINFO:
1704                {
1705                    FontsInfoDlg *d = new FontsInfoDlg( hWndFrame, doc );
1706                    d->doDialog();
1707                    return (MRESULT)FALSE;
1708                }
1709
1710                case CM_PLUGINSLIST:
1711                {
1712                    PluginViewDlg *d = new PluginViewDlg( hWndFrame,
1713                                                pluginMan->getPluginsList() );
1714                    d->doDialog();
1715                    return (MRESULT)FALSE;
1716                }
1717
1718                case CM_COPY:
1719                    docViewer->copyToClipbrd();
1720                    return (MRESULT)FALSE;
1721
1722                case CM_SELECTALL:
1723                    docViewer->selectAll();
1724                    return (MRESULT)FALSE;
1725
1726                case CM_FIND:
1727                    if ( findDlg->showDialog() == DID_OK ) {
1728                        if ( strlen( findDlg->getSearchString() ) >= 0 )
1729                        {
1730                            bool clear = TRUE;
1731                            docViewer->searchDocument( findDlg->getSearchString(),
1732                                            findDlg->isCaseSensitive(), false, findDlg->doFindBack() );
1733
1734                            if ( strlen( findDlg->getSearchString() ) == 0 )
1735                                clear = FALSE;
1736                            WinEnableMenuItem( hWndMenu, CM_FINDAGAIN, clear );
1737                            WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FINDAGAIN), (MPARAM)clear );
1738                        }
1739                    }
1740                    return (MRESULT)FALSE;
1741
1742                case CM_FINDAGAIN:
1743                    docViewer->searchDocument( findDlg->getSearchString(),
1744                                               findDlg->isCaseSensitive(), true, findDlg->doFindBack() );
1745                    return (MRESULT)FALSE;
1746
1747                case CM_SETTINGS:
1748                {
1749                    SettingsDlg *d = new SettingsDlg( hWndFrame, settings );
1750                    d->doDialog();
1751                    return (MRESULT)FALSE;
1752                }
1753
1754                case CM_FIRSTPAGE:
1755                    Lucide::goToPage( 0 );
1756                    return (MRESULT)FALSE;
1757
1758                case CM_NEXTPAGE:
1759                    Lucide::goToPage( docViewer->getCurrentPage() + 1 );
1760                    return (MRESULT)FALSE;
1761
1762                case CM_PREVPAGE:
1763                    Lucide::goToPage( docViewer->getCurrentPage() - 1 );
1764                    return (MRESULT)FALSE;
1765
1766                case CM_LASTPAGE:
1767                    Lucide::goToPage( doc->getPageCount( ev ) - 1 );
1768                    return (MRESULT)FALSE;
1769
1770                case CM_GOTOPAGE:
1771                {
1772                    GotoDlg *d = new GotoDlg( hWndFrame, doc->getPageCount( ev ),
1773                                                docViewer->getCurrentPage() + 1 );
1774                    if ( d->showDialog() == DID_OK ) {
1775                        long pg = d->getPage();
1776                        if ( pg > 0 ) {
1777                            Lucide::goToPage( pg - 1 );
1778                        }
1779                    }
1780                    delete d;
1781                    return (MRESULT)FALSE;
1782                }
1783
1784                case CM_FITWINDOW:
1785                    Lucide::setZoom( -2 );
1786                    return (MRESULT)FALSE;
1787
1788                case CM_ACTSIZE:
1789                    Lucide::setZoom( 1 );
1790                    return (MRESULT)FALSE;
1791
1792                case CM_FITWIDTH:
1793                    Lucide::setZoom( -1 );
1794                    return (MRESULT)FALSE;
1795
1796                case CM_ZOOM_IN_OUT:
1797                    Lucide::toggleZoom();
1798                    return (MRESULT)FALSE;
1799
1800                case CM_ZOOM_IN:
1801                    docViewer->zoomInOut( true );
1802                    return (MRESULT)FALSE;
1803
1804                case CM_ZOOM_OUT:
1805                    docViewer->zoomInOut( false );
1806                    return (MRESULT)FALSE;
1807
1808                case CM_SINGLEPAGE:
1809                    Lucide::setPageLayout( SinglePage );
1810                    return (MRESULT)FALSE;
1811
1812                case CM_CONTINUOUS:
1813                    Lucide::setPageLayout( Continuous );
1814                    return (MRESULT)FALSE;
1815
1816                case CM_ROTATE90CW:
1817                    docViewer->setRotation( docViewer->getRotation() + 90 );
1818                    return (MRESULT)FALSE;
1819
1820                case CM_ROTATE90CCW:
1821                    docViewer->setRotation( docViewer->getRotation() - 90 );
1822                    return (MRESULT)FALSE;
1823
1824                case CM_NAVPANE:
1825                    {
1826                        Lucide::showIndex = !Lucide::showIndex;
1827                        Lucide::checkNavpane();
1828                        WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS,
1829                            MPFROMSHORT( Lucide::showIndex ? Lucide::splitterPos : 0 ), MPVOID );
1830                        if ( !Lucide::showIndex ) {
1831                            Lucide::focusDocview();
1832                        }
1833                    }
1834                    return (MRESULT)FALSE;
1835
1836                case CM_FULLSCREEN:
1837                    Lucide::toggleFullscreen();
1838                    return (MRESULT)FALSE;
1839
1840                case CM_PRESENTATION:
1841                    Lucide::togglePresentation();
1842                    return (MRESULT)FALSE;
1843
1844                case WM_HELP:
1845                    if (Lucide::hwndHelp)
1846                        WinSendMsg(Lucide::hwndHelp,HM_DISPLAY_HELP,
1847                                   MPFROM2SHORT(1, 0), MPFROMSHORT(HM_RESOURCEID));
1848                    break;
1849
1850                case CM_HELPKEYS:
1851                    if (Lucide::hwndHelp)
1852                            WinSendMsg(Lucide::hwndHelp,HM_DISPLAY_HELP,
1853                                       MPFROM2SHORT(400, 0), MPFROMSHORT(HM_RESOURCEID));
1854                    return (MRESULT)FALSE;
1855
1856                case CM_HELPPDF:
1857                    if (Lucide::hwndHelp)
1858                            WinSendMsg(Lucide::hwndHelp,HM_DISPLAY_HELP,
1859                                       MPFROM2SHORT(710, 0), MPFROMSHORT(HM_RESOURCEID));
1860                    return (MRESULT)FALSE;
1861
1862                case CM_HELPDJVU:
1863                    if (Lucide::hwndHelp)
1864                            WinSendMsg(Lucide::hwndHelp,HM_DISPLAY_HELP,
1865                                       MPFROM2SHORT(780, 0), MPFROMSHORT(HM_RESOURCEID));
1866                    return (MRESULT)FALSE;
1867
1868                case CM_PRODINFO:
1869                    AboutBox( hWndFrame );
1870                    return (MRESULT)FALSE;
1871
1872                case CM_MINIMIZE:
1873                    Lucide::cmdMinimize();
1874                    return (MRESULT)FALSE;
1875
1876                case CM_TOPRESENTATION:
1877                    Lucide::cmdSwitchToPresentation();
1878                    return (MRESULT)FALSE;
1879
1880                case CM_SWITCHWINDOW:
1881                    Lucide::cmdSwitchWindow();
1882                    return (MRESULT)FALSE;
1883            }
1884        }
1885        break;
1886
1887        case WM_CLOSE:
1888            if ( !Lucide::closeDocument() )
1889                return (MRESULT)FALSE;
1890        break;
1891    }
1892    return pOldSplProc( hwnd, msg, mp1, mp2 );
1893}
1894
1895
1896char deffont[] = "9.WarpSans";
1897int deffontlen = sizeof( deffont );
1898
1899__declspec(dllexport) _System APIRET APIENTRY LucideMain( int argc, char *argv[] )
1900{
1901    //ScopedExceptqLoader sel;
1902    HMQ   hmq;
1903    QMSG  qmsg;
1904
1905    hab = WinInitialize( 0 );
1906    hmq = WinCreateMsgQueue( hab, 0 );
1907   
1908    loadLang();
1909    // Open the INI file
1910    Lucide::openProfile();
1911
1912    pluginMan = new PluginManager;
1913
1914    InitPMSplitterClass( hab );
1915    InitPMToolbarClass( hab );
1916
1917    ULONG ulFrameFlags = FCF_TITLEBAR | FCF_SIZEBORDER | FCF_SYSMENU |
1918                         FCF_MINMAX | FCF_TASKLIST | FCF_NOBYTEALIGN | FCF_ICON;
1919    title = newstrdupL( MSGS_MAIN_WIN_TITLE );
1920    hWndFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &ulFrameFlags, NULL, title,
1921                                    WS_SYNCPAINT|WS_VISIBLE, _hmod, IDI_MAIN_ICON, NULL );
1922    pOldFrameProc = WinSubclassWindow( hWndFrame, frameProc );
1923    WinSetWindowUShort( hWndFrame, QWS_ID, MAIN_FRAME );
1924
1925    hFrameSysmenu  = WinWindowFromID( hWndFrame, FID_SYSMENU );
1926    hFrameTitlebar = WinWindowFromID( hWndFrame, FID_TITLEBAR );
1927    hFrameMinMax   = WinWindowFromID( hWndFrame, FID_MINMAX );
1928    WinSetAccelTable( hab, WinLoadAccelTable( hab, _hmod, IDA_MAINACCEL ), hWndFrame );
1929    hWndMenu = WinLoadMenu( hWndFrame, _hmod, IDM_MAINMENU );
1930    localizeMenu( hWndMenu );
1931    WinSetWindowUShort( hWndMenu, QWS_ID, FID_MENU );
1932   
1933   
1934    // Vertical splitter and his windows - Index and Document view
1935    hVertSplitter = WinCreateWindow( hWndFrame, WC_ER_SPLITTER, "",
1936                                     WS_VISIBLE | SBS_VSPLIT,
1937                                     0, 0, 0, 0, hWndFrame, HWND_TOP,
1938                                     ID_SPLITTER, NULL, NULL );
1939
1940    indexWin = new IndexWindow( hWndFrame );
1941
1942    DocumentViewer::registerClass();
1943
1944    docViewer = new DocumentViewer( hWndFrame );
1945
1946    WinSendMsg( hVertSplitter, SBM_SETWINDOWS,
1947                MPFROMHWND( indexWin->getHWND() ), MPFROMHWND( docViewer->getFrameHWND() ) );
1948
1949    // Horizontal splitter and its windows - Toolbar and Vertical splitter
1950    // Horizontal splitter is client window
1951    hHorizSplitter = WinCreateWindow( hWndFrame, WC_ER_SPLITTER, "",
1952                                      WS_VISIBLE | SBS_HSPLIT | SBS_SECONDFIXED,
1953                                      0, 0, 0, 0, hWndFrame, HWND_TOP,
1954                                      FID_CLIENT, NULL, NULL );
1955    pOldSplProc = WinSubclassWindow( hHorizSplitter, splProc );
1956
1957    hToolBar = createToolbar( hWndFrame );
1958
1959    WinSendMsg( hHorizSplitter, SBM_SETWINDOWS,
1960                MPFROMHWND( hVertSplitter ), MPFROMHWND( hToolBar ) );
1961   
1962    WinSendMsg( hHorizSplitter, SBM_SETFIXEDSIZE,
1963                MPFROMSHORT( DEFAULT_PICTSIZE + TOOLBAR_HEIGHT_ADD ), MPVOID );
1964
1965    settings = new LuSettings;
1966    settings->load();
1967    Lucide::checkMenus( true );
1968    Lucide::setPageLayout( settings->layout );
1969    Lucide::setZoom( settings->zoom );
1970
1971    findDlg = new FindDlg( hWndFrame );
1972    recent  = new RecentFiles( hWndMenu );
1973   
1974    Lucide::restorePosition();
1975
1976    Lucide::focusDocview();
1977
1978    if ( argc > 1 ) {
1979        Lucide::loadDocument( argv[1] );
1980    }
1981
1982    Lucide::checkNavpane();
1983    initPipeMon( hWndFrame );
1984
1985    // start help
1986    FILESTATUS3 fs3;
1987    char helpfile[CCHMAXPATH];
1988    char *env  = getenv("LUCIDEHELP");
1989    if (env)  {
1990        strcpy(helpfile, env);
1991    }
1992    else {
1993        char *lang = getenv("LANG");
1994        if (lang) {
1995            if (!strnicmp(lang, "es", 2)) {      //Spanish
1996                strcpy(helpfile, "lucide_es.hlp");
1997            }
1998            else if (!strnicmp(lang, "de", 2)) { // German
1999                strcpy(helpfile, "lucide_en.hlp"); 
2000            }
2001            else if (!strnicmp(lang, "cs", 2)) { // Czech
2002                strcpy(helpfile, "lucide_en.hlp"); 
2003            }
2004            else if (!strnicmp(lang, "nl", 2)) { // Dutch
2005                strcpy(helpfile, "lucide_en.hlp"); 
2006            }
2007            else if (!strnicmp(lang, "fr", 2)) { // French
2008                strcpy(helpfile, "lucide_en.hlp"); 
2009            }
2010            else if (!strnicmp(lang, "it", 2)) { // Itailian
2011                strcpy(helpfile, "lucide_en.hlp"); 
2012            }
2013            else if (!strnicmp(lang, "da", 2)) { // Norwegian
2014                strcpy(helpfile, "lucide_en.hlp"); 
2015            }
2016            else if (!strnicmp(lang, "ru", 2)) { // Russian
2017                strcpy(helpfile, "lucide_en.hlp"); 
2018            }
2019            else if (!strnicmp(lang, "sv", 2)) { //  Swedish
2020                strcpy(helpfile, "lucide_en.hlp"); 
2021            }
2022            else if (!strnicmp(lang, "zh", 2)) { //  Chinese
2023                strcpy(helpfile, "lucide_en.hlp"); 
2024            }
2025            else if (!strnicmp(lang, "pl", 2)) { //  Polish
2026                strcpy(helpfile, "lucide_en.hlp"); 
2027            }
2028            else {
2029                strcpy(helpfile, "lucide_en.hlp");
2030            }
2031        }
2032        else
2033            strcpy(helpfile, "lucide_en.hlp");
2034    }
2035    char *hlptitle = newstrdupL( HLP_TITLE );
2036    memset(&hini, 0, sizeof(HELPINIT));
2037    hini.cb = sizeof(HELPINIT);
2038    hini.phtHelpTable = (PHELPTABLE) MAKELONG(ID_HELPTABLE, 0xffff);
2039    hini.hmodAccelActionBarModule = (HMODULE) 0;
2040    hini.pszHelpWindowTitle = (PSZ) hlptitle; //"Lucide User's Guide";
2041    hini.hmodHelpTableModule = _hmod;
2042    hini.fShowPanelId = CMIC_HIDE_PANEL_ID;
2043    hini.pszHelpLibraryName = helpfile;
2044    Lucide::hwndHelp = WinCreateHelpInstance(hab, &hini);
2045    if (!Lucide::hwndHelp) {
2046        char helppath[CCHMAXPATH];
2047        char *env = getenv("LUCIDEINSTALLPATH");
2048        if (env) {
2049            strcpy(helppath, env);
2050            DosError(FERR_DISABLEHARDERR);
2051            if (!DosQueryPathInfo(helppath, FIL_STANDARD, &fs3, sizeof(fs3))) {
2052                if (fs3.attrFile & FILE_DIRECTORY) {
2053                    if (strrchr(helppath, '\\') != helppath + strlen(helppath))
2054                        strcat(helppath, "\\");
2055                    strcat(helppath,  helpfile); 
2056                    hini.pszHelpLibraryName = (CHAR *) helppath;
2057                    Lucide::hwndHelp = WinCreateHelpInstance(hab, &hini);
2058                    if (!Lucide::hwndHelp) {
2059                        char *msg = newstrdupL( MSGS_HELP_INSTANCE_FAILED );
2060                        WinMessageBox( HWND_DESKTOP, hWndFrame, msg,
2061                                      NULL, 0, MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE );
2062                        delete msg;
2063                    }
2064                }
2065            }
2066        }
2067    }
2068    delete hlptitle;
2069    if ( Lucide::hwndHelp )
2070        WinAssociateHelpInstance ( Lucide::hwndHelp, hWndFrame );
2071   
2072    // Messsage loop
2073    while ( WinGetMsg( hab, &qmsg, 0, 0, 0 ) ) {
2074        WinDispatchMsg( hab, &qmsg );
2075    }
2076
2077    Lucide::savePosition();
2078
2079    WinDestroyWindow( hWndFrame );
2080
2081    recent->save();
2082
2083    PrfCloseProfile(hinilucideprofile);
2084
2085    Lucide::closeDocument( true );
2086
2087    delete docViewer;
2088    delete indexWin;
2089
2090    // must be freed _after_ document
2091    delete pluginMan;
2092
2093    delete findDlg;
2094    delete recent;
2095    delete title;
2096    delete settings;
2097    unInitPipeMon();
2098
2099    WinDestroyMsgQueue( hmq );
2100    WinTerminate( hab );
2101    return 0;
2102}
2103
Note: See TracBrowser for help on using the repository browser.