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

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

Fixed file navigation with Shift+PgUp/PgDown/Home/End? broken in version 1.30 (due to the switch from Watcom to GCC with its unix-like forward slashes). Fixes ticket:175.

File size: 56.5 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 *prfFullscreen   = "FullScreen";
89const char *prfPresentation = "Presentation";
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::isFullscreen                  = false;
123bool         Lucide::isPresentation                = 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 = buf + strlen( buf );
622    while ( r >= buf && *r != '\\' && *r != '/')
623        --r;
624    if ( r >= buf )
625    {
626        *( r + 1 ) = 0;
627        strcat( buf, mask );
628
629        find_t ffblk;
630        unsigned done = _dos_findfirst( buf, _A_RDONLY | _A_NORMAL, &ffblk );
631        while ( done == 0 )
632        {
633            fileList.insert( find_t_name( ffblk ) );
634            done = _dos_findnext( &ffblk );
635        }
636        _dos_findclose( &ffblk );
637
638    }
639    delete buf;
640}
641
642void Lucide::loadFileList()
643{
644    fileList.clear();
645
646    char *exts = newstrdup( pluginMan->getExtsMask().c_str() );
647
648    char *p = strtok( exts, ";" );
649    while ( p != NULL )
650    {
651        readMask( p );
652        p = strtok( NULL, ";" );
653    }
654    delete exts;
655
656    fileListIterator = fileList.find( docFileName );
657}
658
659void Lucide::openDocument()
660{
661    PFILEDLG fd = new FILEDLG;
662    memset( fd, 0, sizeof( FILEDLG ) );
663    fd->cbSize = sizeof( FILEDLG );
664    fd->fl = FDS_CENTER | FDS_OPEN_DIALOG;
665    PrfQueryProfileString( HINI_USERPROFILE, appName, prfLvd, "",
666                           fd->szFullFile, sizeof( fd->szFullFile ) );
667    LcdFileDlg( HWND_DESKTOP, hWndFrame, fd );
668    if ( fd->lReturn == DID_OK )
669    {
670        char drv[ _MAX_DRIVE ] = "";
671        char dir[ _MAX_PATH ] = "";
672        char buf[ _MAX_PATH ] = "";
673        _splitpath( fd->szFullFile, drv, dir, NULL, NULL );
674        _makepath( buf, drv, dir, NULL, NULL );
675        PrfWriteProfileString( HINI_USERPROFILE, appName, prfLvd, buf );
676
677        loadDocument( fd->szFullFile );
678    }
679    delete fd;
680}
681
682bool Lucide::saveDocumentAs()
683{
684    bool saved = false;
685
686    char dirbuf[ CCHMAXPATH ];
687    PFILEDLG fd = new FILEDLG;
688    memset( fd, 0, sizeof( FILEDLG ) );
689    fd->cbSize = sizeof( FILEDLG );
690    fd->fl = FDS_CENTER | FDS_SAVEAS_DIALOG;
691    PrfQueryProfileString( HINI_USERPROFILE, appName, prfLvd, "",
692                           dirbuf, sizeof( dirbuf ) );
693    char fil[ _MAX_FNAME ] = "";
694    char ext[ _MAX_EXT ] = "";
695    _splitpath( docFullName, NULL, NULL, fil, ext );
696    char filcopy[ _MAX_FNAME ] = "";
697    snprintf( filcopy, sizeof( filcopy ),
698              getLocalizedString( MSGS_FILE_COPY_SUFFIX ).c_str(), fil );
699    snprintf( fd->szFullFile, sizeof( fd->szFullFile ),
700              "%s%s%s", dirbuf, filcopy, ext );
701    WinFileDlg( HWND_DESKTOP, hWndFrame, fd );
702    if ( fd->lReturn == DID_OK )
703    {
704        bool doSave = true;
705        if ( access( fd->szFullFile, F_OK ) == 0 )
706        {
707            char *t = newstrdupL( MSGS_WARNING );
708            char *m = newstrdupL( MSGS_OVERWRITE_FILE );
709            ULONG response = WinMessageBox( HWND_DESKTOP, hWndFrame, m, t,
710                                            0, MB_YESNO | MB_WARNING | MB_MOVEABLE );
711            delete m;
712            delete t;
713
714            doSave = ( response == MBID_YES );
715        }
716        if ( doSave )
717        {
718            // @todo poppler has troubles saving to the same file name
719            // (some locking issues) so forbid it for now
720            if ( ( saved = false, stricmp( docFullName, fd->szFullFile ) == 0 ) ||
721                 !( saved = doc->saveAs( ev, fd->szFullFile ) ) )
722            {
723                char *m = newstrdupL( MSGS_FILE_SAVE_ERROR );
724                WinMessageBox( HWND_DESKTOP, hWndFrame, m, NULL,
725                               0, MB_OK | MB_ERROR | MB_MOVEABLE );
726                delete m;
727            }
728            else
729            {
730                if ( stricmp( docFullName, fd->szFullFile ) == 0 )
731                    docViewer->resetModifiedState();
732            }
733        }
734    }
735    delete fd;
736
737    return saved;
738}
739
740void Lucide::checkNavpane()
741{
742    if ( Lucide::showIndex ) {
743        WinCheckMenuItem( hWndMenu, CM_NAVPANE, TRUE );
744        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_NAVPANE ), (MPARAM)TRUE );
745    }
746    else {
747        WinCheckMenuItem( hWndMenu, CM_NAVPANE, FALSE );
748        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_NAVPANE ), (MPARAM)FALSE );
749    }
750}
751
752
753void Lucide::toggleFullscreenEx( bool presentation, bool atStartup )
754{
755    enum TriState { NoChange, On, Off };
756    TriState fullscreenState = NoChange;
757    TriState presentationState = NoChange;
758
759    if ( !presentation )
760    {
761        // fullscreen command issued
762        if ( !isFullscreen )
763        {
764            if ( isPresentation ) {
765                presentationState = Off;
766                isPresentation = false;
767            } else {
768                fullscreenState = On;
769            }
770            isFullscreen = true;
771        }
772        else
773        {
774            if ( isPresentation ) {
775                presentationState = Off;
776                isPresentation = false;
777            } else {
778                fullscreenState = Off;
779                isFullscreen = false;
780            }
781        }
782    }
783    else
784    {
785        // presentation command issued
786        if ( !isPresentation )
787        {
788            presentationState = On;
789            if ( !isFullscreen )
790                fullscreenState = On;
791        }
792        else
793        {
794            presentationState = Off;
795            if ( !isFullscreen )
796                fullscreenState = Off;
797        }
798
799        isPresentation = !isPresentation;
800    }
801
802    ULONG ulFrameStyle = WinQueryWindowULong( hWndFrame, QWL_STYLE );
803
804    if ( presentationState == Off )
805    {
806        docViewer->setPresentation( false );
807        WinSetParent( hWndMenu, hWndFrame, FALSE );
808    }
809    else if ( presentationState == On )
810    {
811        docViewer->setPresentation( true );
812        WinSetParent( hWndMenu, HWND_OBJECT, FALSE );
813    }
814
815    if ( fullscreenState == Off )
816    {
817        WinSetParent( hFrameSysmenu,  hWndFrame, FALSE );
818        WinSetParent( hFrameTitlebar, hWndFrame, FALSE );
819        WinSetParent( hFrameMinMax,   hWndFrame, FALSE );
820        ulFrameStyle |= FS_SIZEBORDER;
821
822        // PM does not synchronize the title bar hilite state when it is added
823        // to the frame window. Do it ourselves
824        BOOL active = WinQueryActiveWindow( HWND_DESKTOP ) == hWndFrame;
825        WinSendMsg( hFrameTitlebar, TBM_SETHILITE,
826                    MPFROMSHORT( active ), MPVOID );
827    }
828    else if ( fullscreenState == On )
829    {
830        if ( !atStartup )
831        {
832            WinQueryWindowPos( hWndFrame, &winPos.Swp );
833            winPos.XRestore  = WinQueryWindowUShort( hWndFrame, QWS_XRESTORE );
834            winPos.YRestore  = WinQueryWindowUShort( hWndFrame, QWS_YRESTORE );
835            winPos.CXRestore = WinQueryWindowUShort( hWndFrame, QWS_CXRESTORE );
836            winPos.CYRestore = WinQueryWindowUShort( hWndFrame, QWS_CYRESTORE );
837            winPos.XMinimize = WinQueryWindowUShort( hWndFrame, QWS_XMINIMIZE );
838            winPos.YMinimize = WinQueryWindowUShort( hWndFrame, QWS_YMINIMIZE );
839        }
840
841        WinSetParent( hFrameSysmenu,  HWND_OBJECT, FALSE );
842        WinSetParent( hFrameTitlebar, HWND_OBJECT, FALSE );
843        WinSetParent( hFrameMinMax,   HWND_OBJECT, FALSE );
844        ulFrameStyle &= ~FS_SIZEBORDER;
845    }
846
847    if ( fullscreenState != NoChange || presentationState != NoChange )
848    {
849        WinSetWindowULong( hWndFrame, QWL_STYLE, ulFrameStyle );
850        WinSendMsg( hWndFrame, WM_UPDATEFRAME, MPVOID, MPVOID );
851    }
852
853    if ( presentationState == Off )
854    {
855        WinSendMsg( hVertSplitter, SBM_SETSPLITTERSIZE, MPFROMSHORT( -1 ), MPVOID );
856        WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS,
857                    MPFROMSHORT( Lucide::showIndex ? Lucide::splitterPos : 0 ), MPVOID );
858        WinSendMsg( hHorizSplitter, SBM_SETFIXEDSIZE,
859            MPFROMSHORT( DEFAULT_PICTSIZE + TOOLBAR_HEIGHT_ADD ), MPVOID );
860    }
861    else if ( presentationState == On )
862    {
863        WinSendMsg( hHorizSplitter, SBM_SETSPLITTERPOS, 0, MPVOID );
864        WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS, 0, MPVOID );
865        WinSendMsg( hVertSplitter, SBM_SETSPLITTERSIZE, 0, MPVOID );
866    }
867
868    if ( fullscreenState == Off )
869    {
870        WinSetWindowUShort( hWndFrame, QWS_XRESTORE,  winPos.XRestore );
871        WinSetWindowUShort( hWndFrame, QWS_YRESTORE,  winPos.YRestore );
872        WinSetWindowUShort( hWndFrame, QWS_CXRESTORE, winPos.CXRestore );
873        WinSetWindowUShort( hWndFrame, QWS_CYRESTORE, winPos.CYRestore );
874        WinSetWindowUShort( hWndFrame, QWS_XMINIMIZE, winPos.XMinimize );
875        WinSetWindowUShort( hWndFrame, QWS_YMINIMIZE, winPos.YMinimize );
876        WinSetWindowPos( hWndFrame, NULLHANDLE,
877                         winPos.Swp.x, winPos.Swp.y, winPos.Swp.cx, winPos.Swp.cy,
878                         SWP_SIZE | SWP_MOVE | SWP_SHOW );
879    }
880    else if ( fullscreenState == On )
881    {
882        WinSetWindowPos( hWndFrame, NULLHANDLE, 0, 0,
883                         WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ),
884                         WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ),
885                         SWP_SIZE | SWP_MOVE | SWP_SHOW );
886    }
887}
888
889
890void Lucide::focusDocview()
891{
892    WinSetFocus( HWND_DESKTOP, docViewer->getViewHWND() );
893}
894
895void Lucide::focusIndex()
896{
897    WinSetFocus( HWND_DESKTOP, indexWin->getIndexHWND() );
898}
899
900void Lucide::cmdSwitchWindow()
901{
902    if ( activeWindow == AwIndex ) {
903        focusDocview();
904    } else {
905        focusIndex();
906    }
907}
908
909void Lucide::toggleZoom()
910{
911    if ( ( doc != NULL ) && doc->isScalable( ev ) )
912    {
913        bool isZoom = !docViewer->isZoomMode();
914        WinSendMsg( hToolBar, TBM_SETCHECK, MPFROMSHORT( CM_ZOOM_IN_OUT ), (MPARAM)isZoom );
915        docViewer->setZoomMode( isZoom );
916    }
917}
918
919void Lucide::cmdMinimize()
920{
921    if ( isFullscreen ) {
922        toggleFullscreen();
923    }
924    WinSetWindowPos( hWndFrame, HWND_TOP, 0, 0, 0, 0, SWP_MINIMIZE );
925}
926
927void Lucide::cmdSwitchToPresentation()
928{
929    if ( !isPresentation )
930    {
931        SWP pos = {0};
932        WinQueryWindowPos( hWndFrame, &pos );
933
934        if ( pos.fl & SWP_MINIMIZE ) {
935            WinSetWindowPos( hWndFrame, HWND_TOP, 0, 0, 0, 0,
936                    SWP_SHOW | SWP_ACTIVATE | SWP_RESTORE | SWP_ZORDER );
937        }
938        togglePresentation();
939    }
940}
941
942void Lucide::newWindow( char *file, bool addDir )
943{
944    char *param = NULL;
945
946    if ( file != NULL )
947    {
948        if ( addDir )
949        {
950            param = new char[ CCHMAXPATH ];
951            strcpy( param, docFullName );
952            char *lastSlash = strrchr( param, '\\' );
953            if ( lastSlash != NULL ) {
954                *( lastSlash + 1 ) = 0;
955            }
956            strcat( param, file );
957        }
958        else {
959            param = newstrdup( file );
960        }
961    }
962
963#if defined(__WATCOM__)
964    const char *execname = __argv[0];
965#else
966    char execname[ _MAX_PATH ];
967    _execname( execname, sizeof(execname) );
968#endif
969
970    PROGDETAILS pd;
971    pd.Length                      = sizeof( PROGDETAILS );
972    pd.progt.progc                 = PROG_DEFAULT;
973    pd.progt.fbVisible             = SHE_VISIBLE;
974    pd.pszTitle                    = NULL;
975    pd.pszExecutable               = execname;
976    pd.pszParameters               = NULL;
977    pd.pszStartupDir               = NULL;
978    pd.pszIcon                     = NULL;
979    pd.pszEnvironment              = NULL;
980    pd.swpInitial.fl               = SWP_ACTIVATE;
981    pd.swpInitial.cy               = 0;
982    pd.swpInitial.cx               = 0;
983    pd.swpInitial.y                = 0;
984    pd.swpInitial.x                = 0;
985    pd.swpInitial.hwndInsertBehind = HWND_TOP;
986    pd.swpInitial.hwnd             = NULLHANDLE;
987    pd.swpInitial.ulReserved1      = 0;
988    pd.swpInitial.ulReserved2      = 0;
989
990    WinStartApp( NULLHANDLE, &pd, param, NULL, 0 );
991
992    delete param;
993}
994
995void Lucide::gotoFile( FileList file )
996{
997    if ( fileList.size() == 0 ) {
998        return;
999    }
1000
1001    if ( fileListIterator == fileList.end() ) {
1002        // If viewed file extension not in supported extensions
1003        //   list - fileListIterator will equal fileList.end()
1004        fileListIterator = fileList.begin();
1005    }
1006
1007    if ( file == ListFirst ) {
1008        fileListIterator = fileList.begin();
1009    }
1010    else if ( file == ListPrevious )
1011    {
1012        if ( fileListIterator == fileList.begin() ) {
1013            fileListIterator = fileList.end();
1014        }
1015        fileListIterator--;
1016    }
1017    else if ( file == ListNext )
1018    {
1019        fileListIterator++;
1020        if ( fileListIterator == fileList.end() ) {
1021            fileListIterator = fileList.begin();
1022        }
1023    }
1024    else if ( file == ListLast ) {
1025        fileListIterator = fileList.end();
1026        fileListIterator--;
1027    }
1028
1029    std::string fname = *fileListIterator;
1030    char *fn = new char[ CCHMAXPATH ];
1031    strcpy( fn, docDirName );
1032    strcat( fn, fname.c_str() );
1033
1034    loadDocument( fn );
1035    delete fn;
1036}
1037
1038void Lucide::savePosition()
1039{
1040    if ( !WinIsWindow( hab, hWndFrame ) )
1041        return;
1042
1043    char valbuf[ 3 ] = "";
1044    PrfWriteProfileString( HINI_USERPROFILE, appName, prfSplpos,
1045                           itoa( Lucide::splitterPos, valbuf, 10 ) );
1046    PrfWriteProfileString( HINI_USERPROFILE, appName, prfShowind,
1047                           itoa( Lucide::showIndex, valbuf, 10 ) );
1048
1049    if ( isFullscreen )
1050        PrfWriteProfileString( HINI_USERPROFILE, appName, prfFullscreen, "1" );
1051    else
1052        PrfWriteProfileString( HINI_USERPROFILE, appName, prfFullscreen, NULL );
1053
1054    if ( isPresentation )
1055        PrfWriteProfileString( HINI_USERPROFILE, appName, prfPresentation, "1" );
1056    else
1057        PrfWriteProfileString( HINI_USERPROFILE, appName, prfPresentation, NULL );
1058
1059    if ( !isFullscreen && !isPresentation ) {
1060        WinQueryWindowPos( hWndFrame, &winPos.Swp );
1061        winPos.XRestore  = WinQueryWindowUShort( hWndFrame, QWS_XRESTORE );
1062        winPos.YRestore  = WinQueryWindowUShort( hWndFrame, QWS_YRESTORE );
1063        winPos.CXRestore = WinQueryWindowUShort( hWndFrame, QWS_CXRESTORE );
1064        winPos.CYRestore = WinQueryWindowUShort( hWndFrame, QWS_CYRESTORE );
1065        winPos.XMinimize = WinQueryWindowUShort( hWndFrame, QWS_XMINIMIZE );
1066        winPos.YMinimize = WinQueryWindowUShort( hWndFrame, QWS_YMINIMIZE );
1067    }
1068
1069    PrfWriteProfileData( HINI_USERPROFILE, appName, prfFwp, &winPos, sizeof( winPos ) );
1070}
1071
1072void Lucide::restorePosition()
1073{
1074    splitterPos = PrfQueryProfileInt( HINI_USERPROFILE, appName, prfSplpos,
1075                                      Lucide::splitterPos );
1076    showIndex = PrfQueryProfileInt( HINI_USERPROFILE, appName, prfShowind,
1077                                    Lucide::showIndex );
1078
1079    WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS,
1080                MPFROMSHORT( showIndex ? splitterPos : 0 ), MPVOID );
1081
1082    bool fullscreen = PrfQueryProfileInt( HINI_USERPROFILE, appName,
1083                                          prfFullscreen, 0 ) == 1;
1084    bool presentation = PrfQueryProfileInt( HINI_USERPROFILE, appName,
1085                                            prfPresentation, 0 ) == 1;
1086
1087    LONG sx, sy;
1088    sx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
1089    sy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
1090
1091    ULONG SwpOptions = SWP_MOVE | SWP_SIZE | SWP_ACTIVATE | SWP_SHOW;
1092    bool atStartup = true;
1093
1094    ULONG ulWpSize = sizeof( winPos );
1095    if ( PrfQueryProfileData( HINI_USERPROFILE, appName, prfFwp, &winPos, &ulWpSize ) )
1096    {
1097        if ( winPos.Swp.fl & SWP_MAXIMIZE ) {
1098            SwpOptions |= SWP_MAXIMIZE;
1099        }
1100        else if ( winPos.Swp.fl & SWP_MINIMIZE ) {
1101            SwpOptions |= SWP_MINIMIZE;
1102        }
1103
1104        LONG sx, sy;
1105        sx = WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
1106        sy = WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
1107
1108        if ( winPos.Swp.x > sx ) {
1109            winPos.Swp.x = sx - winPos.Swp.cx;
1110        }
1111        if ( winPos.Swp.y > sy ) {
1112            winPos.Swp.y = sy - winPos.Swp.cy;
1113        }
1114
1115        // Just a note: the FID_CLIENT window is only resized by WinSetWindowPos()
1116        // on the frame if the size is actually changed *and* the SWP_SHOW flag
1117        // is present (PM bug?). Therefore, when the saved normal size the same
1118        // as fullscreen and we should go fullscreen at startup, WinSetWindowPos()
1119        // issued from toggleFullscreenEx() will not resize FID_CLIENT even
1120        // though it will contain SWP_SHOW
1121
1122        if ( !fullscreen && !presentation ) {
1123            // only set the normal size if no if fullscreen or presentation is
1124            // requested, to avoid flicker. We could also avoid flicker by
1125            // omitting SWP_SHOW but see the note above
1126            WinSetWindowPos( hWndFrame, NULLHANDLE,
1127                             winPos.Swp.x, winPos.Swp.y, winPos.Swp.cx, winPos.Swp.cy,
1128                             SwpOptions );
1129        }
1130
1131        WinSetWindowUShort( hWndFrame, QWS_XRESTORE,  winPos.XRestore );
1132        WinSetWindowUShort( hWndFrame, QWS_YRESTORE,  winPos.YRestore );
1133        WinSetWindowUShort( hWndFrame, QWS_CXRESTORE, winPos.CXRestore );
1134        WinSetWindowUShort( hWndFrame, QWS_CYRESTORE, winPos.CYRestore );
1135        WinSetWindowUShort( hWndFrame, QWS_XMINIMIZE, winPos.XMinimize );
1136        WinSetWindowUShort( hWndFrame, QWS_YMINIMIZE, winPos.YMinimize );
1137
1138        // we don't the app to be minimized at startup
1139        if ( SwpOptions & SWP_MINIMIZE )
1140            WinSetWindowPos( hWndFrame, NULLHANDLE, 0, 0, 0, 0, SWP_RESTORE );
1141    }
1142    else
1143    {
1144        typedef
1145        BOOL ( APIENTRY *WinQueryDesktopWorkArea_T ) ( HWND hwndDesktop,
1146                                                       PRECTL pwrcWorkArea );
1147        static WinQueryDesktopWorkArea_T WinQueryDesktopWorkArea =
1148            (WinQueryDesktopWorkArea_T) ~0;
1149
1150        if ( (ULONG) WinQueryDesktopWorkArea == (ULONG) ~0 ) {
1151            if ( my_DosQueryProcAddr( "PMMERGE", 5469,
1152                                      (PFN *) &WinQueryDesktopWorkArea ) )
1153                WinQueryDesktopWorkArea = NULL;
1154        }
1155
1156        SWP swp;
1157        RECTL rcl;
1158        if ( WinQueryDesktopWorkArea &&
1159             WinQueryDesktopWorkArea( HWND_DESKTOP, &rcl ) ) {
1160            swp.x = rcl.xLeft;
1161            swp.y = rcl.yBottom;
1162            swp.cx = rcl.xRight - rcl.xLeft;
1163            swp.cy = rcl.yTop - rcl.yBottom;
1164        } else {
1165            swp.x = 0;
1166            swp.y = 0;
1167            swp.cx = sx;
1168            swp.cy = sy;
1169        }
1170
1171        swp.x += 16;
1172        swp.y += 16;
1173        swp.cx -= 32;
1174        swp.cy -= 32;
1175
1176        WinSetWindowPos( hWndFrame, NULLHANDLE, swp.x, swp.y, swp.cx, swp.cy,
1177                         SwpOptions );
1178
1179        // we don't initialize winPos here so reset atStartup to let
1180        // toggleFullscreenEx() do this
1181        atStartup = false;
1182    }
1183
1184    if ( fullscreen )
1185    {
1186        toggleFullscreenEx( false, atStartup );
1187        isFullscreen = fullscreen;
1188    }
1189    else if ( presentation )
1190    {
1191        toggleFullscreenEx( true, atStartup );
1192    }
1193}
1194
1195static MRESULT EXPENTRY frameProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
1196{
1197    switch ( msg )
1198    {
1199        case WM_TRANSLATEACCEL:
1200        {
1201            // change the accel logic by first letting the focus window process
1202            // WM_CHAR and only translate it to accel if not handled (this makes
1203            // sure that keyboard shortcuts in input fields work even if we
1204            // defined our own accelerators from these shortcuts). Make an
1205            // exception for VK_TAB since it's always eaten by the standard
1206            // window procedure and therefore the accel table will never be
1207            // called
1208            PQMSG pqmsg = (PQMSG)mp1;
1209            if ( !( SHORT1FROMMP( pqmsg->mp1 ) & KC_VIRTUALKEY ) ||
1210                 !( SHORT2FROMMP( pqmsg->mp2 ) == VK_TAB ) )
1211            {
1212                HWND focus = WinQueryFocus( HWND_DESKTOP );
1213                if ( focus == pqmsg->hwnd && focus != hwnd ) {
1214                    if ( WinDispatchMsg( hab, pqmsg ) ) {
1215                        pqmsg->msg = WM_NULL;
1216                        return (MRESULT)TRUE;
1217                    }
1218                }
1219            }
1220            // in presentation mode, we hide the menu which effectively makes
1221            // all disabled items work through accelerators which is completely
1222            // unexpected. Fix it by translating accels manually and checking
1223            // if they are disabled in the hidden menu
1224            if ( WinTranslateAccel( hab, hwnd, WinQueryAccelTable( hab, hwnd ),
1225                                    pqmsg ) )
1226            {
1227                if ( pqmsg->msg == WM_COMMAND ) {
1228                    SHORT cm = SHORT1FROMMP(pqmsg->mp1);
1229                    if ( !WinIsMenuItemEnabled( hWndMenu, cm ) )
1230                        pqmsg->msg = WM_NULL;
1231                }
1232                return (MRESULT)TRUE;
1233            }
1234            return (MRESULT)FALSE;
1235        }
1236
1237        case WM_SYSCOMMAND:
1238        {
1239            if ( SHORT1FROMMP(mp1) == SC_CLOSE ) {
1240                // the system menu is disabled in fullscreen/presentation mode
1241                // but we still want to exit with Alt-F4 so always handle it here
1242                WinPostMsg( hWndFrame, WM_CLOSE, NULL, NULL );
1243                return (MRESULT)FALSE;
1244            }
1245        }
1246        break;
1247    }
1248
1249    return pOldFrameProc( hwnd, msg, mp1, mp2 );
1250}
1251
1252static MRESULT EXPENTRY splProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
1253{
1254    switch ( msg )
1255    {
1256        case WM_CONTROL:
1257        {
1258            if ( ( SHORT1FROMMP( mp1 ) == ID_SPLITTER ) &&
1259                 ( SHORT2FROMMP( mp1 ) == SBN_POSITIONCHANGED ) )
1260            {
1261                SHORT pos = SHORT1FROMMP( mp2 );
1262                if ( pos > 0 ) {
1263                    Lucide::splitterPos = pos;
1264                    Lucide::showIndex = true;
1265                }
1266                else {
1267                    Lucide::showIndex = false;
1268                }
1269                Lucide::checkNavpane();
1270            }
1271        }
1272        break;
1273
1274        case WM_COMMAND:
1275        {
1276            switch ( SHORT1FROMMP(mp1) )
1277            {
1278                case CM_NEW_WINDOW:
1279                    Lucide::newWindow( NULL, false );
1280                    return (MRESULT)FALSE;
1281
1282                case CM_OPEN:
1283                    Lucide::openDocument();
1284                    return (MRESULT)FALSE;
1285
1286                case CM_FILEFIRST:
1287                    Lucide::gotoFile( ListFirst );
1288                    return (MRESULT)FALSE;
1289
1290                case CM_FILEPREVIOUS:
1291                    Lucide::gotoFile( ListPrevious );
1292                    return (MRESULT)FALSE;
1293
1294                case CM_FILENEXT:
1295                    Lucide::gotoFile( ListNext );
1296                    return (MRESULT)FALSE;
1297
1298                case CM_FILELAST:
1299                    Lucide::gotoFile( ListLast );
1300                    return (MRESULT)FALSE;
1301
1302                case CM_RECENT + 1:
1303                case CM_RECENT + 2:
1304                case CM_RECENT + 3:
1305                case CM_RECENT + 4:
1306                case CM_RECENT + 5:
1307                case CM_RECENT + 6:
1308                case CM_RECENT + 7:
1309                case CM_RECENT + 8:
1310                case CM_RECENT + 9:
1311                {
1312                    std::string f = recent->getFile( SHORT1FROMMP(mp1) );
1313                    Lucide::loadDocument( f.c_str() );
1314                    return (MRESULT)FALSE;
1315                }
1316
1317                case CM_RECENTCLEAR:
1318                    recent->clear();
1319                    return (MRESULT)FALSE;
1320
1321                case CM_SAVEAS:
1322                    Lucide::saveDocumentAs();
1323                    return (MRESULT)FALSE;
1324
1325                case CM_CLOSE:
1326                    Lucide::closeDocument();
1327                    return (MRESULT)FALSE;
1328
1329                case CM_PRINT:
1330                {
1331                    PrintDlg *d = new PrintDlg( hWndFrame, doc, Lucide::docFileName,
1332                                                docViewer->getCurrentPage() + 1 );
1333                    if ( d->showDialog() == DID_OK )
1334                    {
1335                        // print
1336                        PrintSetup *p = new PrintSetup;
1337                        memset( p, 0, sizeof( PrintSetup ) );
1338                        d->getPrintSetup( p );
1339                        printDocument( hWndFrame, doc, Lucide::docFileName, p );
1340                        delete p;
1341                    }
1342                    delete d;
1343                    return (MRESULT)FALSE;
1344                }
1345
1346                case CM_EXIT:
1347                    WinPostMsg( hWndFrame, WM_CLOSE, NULL, NULL );
1348                    return (MRESULT)FALSE;
1349
1350                case CM_DOCINFO:
1351                {
1352                    LuDocumentInfo *dinfo = doc->getDocumentInfo( ev );
1353                    DocInfoDlg *d = new DocInfoDlg( hWndFrame, dinfo );
1354                    d->doDialog();
1355                    LuDocument::freeDocumentInfo( ev, dinfo );
1356                    return (MRESULT)FALSE;
1357                }
1358
1359                case CM_FONTSINFO:
1360                {
1361                    FontsInfoDlg *d = new FontsInfoDlg( hWndFrame, doc );
1362                    d->doDialog();
1363                    return (MRESULT)FALSE;
1364                }
1365
1366                case CM_PLUGINSLIST:
1367                {
1368                    PluginViewDlg *d = new PluginViewDlg( hWndFrame,
1369                                                pluginMan->getPluginsList() );
1370                    d->doDialog();
1371                    return (MRESULT)FALSE;
1372                }
1373
1374                case CM_COPY:
1375                    docViewer->copyToClipbrd();
1376                    return (MRESULT)FALSE;
1377
1378                case CM_SELECTALL:
1379                    docViewer->selectAll();
1380                    return (MRESULT)FALSE;
1381
1382                case CM_FIND:
1383                    if ( findDlg->showDialog() == DID_OK ) {
1384                        if ( strlen( findDlg->getSearchString() ) > 0 )
1385                        {
1386                            docViewer->searchDocument( findDlg->getSearchString(),
1387                                            findDlg->isCaseSensitive(), false );
1388
1389                            WinEnableMenuItem( hWndMenu, CM_FINDAGAIN, TRUE );
1390                            WinSendMsg( hToolBar, TBM_ENABLEITEM, MPFROMSHORT(CM_FINDAGAIN), (MPARAM)TRUE );
1391                        }
1392                    }
1393                    return (MRESULT)FALSE;
1394
1395                case CM_FINDAGAIN:
1396                    docViewer->searchDocument( findDlg->getSearchString(),
1397                                               findDlg->isCaseSensitive(), true );
1398                    return (MRESULT)FALSE;
1399
1400                case CM_SETTINGS:
1401                {
1402                    SettingsDlg *d = new SettingsDlg( hWndFrame, settings );
1403                    d->doDialog();
1404                    return (MRESULT)FALSE;
1405                }
1406
1407                case CM_FIRSTPAGE:
1408                    Lucide::goToPage( 0 );
1409                    return (MRESULT)FALSE;
1410
1411                case CM_NEXTPAGE:
1412                    Lucide::goToPage( docViewer->getCurrentPage() + 1 );
1413                    return (MRESULT)FALSE;
1414
1415                case CM_PREVPAGE:
1416                    Lucide::goToPage( docViewer->getCurrentPage() - 1 );
1417                    return (MRESULT)FALSE;
1418
1419                case CM_LASTPAGE:
1420                    Lucide::goToPage( doc->getPageCount( ev ) - 1 );
1421                    return (MRESULT)FALSE;
1422
1423                case CM_GOTOPAGE:
1424                {
1425                    GotoDlg *d = new GotoDlg( hWndFrame, doc->getPageCount( ev ),
1426                                                docViewer->getCurrentPage() + 1 );
1427                    if ( d->showDialog() == DID_OK ) {
1428                        long pg = d->getPage();
1429                        if ( pg > 0 ) {
1430                            Lucide::goToPage( pg - 1 );
1431                        }
1432                    }
1433                    delete d;
1434                    return (MRESULT)FALSE;
1435                }
1436
1437                case CM_FITWINDOW:
1438                    Lucide::setZoom( -2 );
1439                    return (MRESULT)FALSE;
1440
1441                case CM_ACTSIZE:
1442                    Lucide::setZoom( 1 );
1443                    return (MRESULT)FALSE;
1444
1445                case CM_FITWIDTH:
1446                    Lucide::setZoom( -1 );
1447                    return (MRESULT)FALSE;
1448
1449                case CM_ZOOM_IN_OUT:
1450                    Lucide::toggleZoom();
1451                    return (MRESULT)FALSE;
1452
1453                case CM_ZOOM_IN:
1454                    docViewer->zoomInOut( true );
1455                    return (MRESULT)FALSE;
1456
1457                case CM_ZOOM_OUT:
1458                    docViewer->zoomInOut( false );
1459                    return (MRESULT)FALSE;
1460
1461                case CM_SINGLEPAGE:
1462                    Lucide::setPageLayout( SinglePage );
1463                    return (MRESULT)FALSE;
1464
1465                case CM_CONTINUOUS:
1466                    Lucide::setPageLayout( Continuous );
1467                    return (MRESULT)FALSE;
1468
1469                case CM_ROTATE90CW:
1470                    docViewer->setRotation( docViewer->getRotation() + 90 );
1471                    return (MRESULT)FALSE;
1472
1473                case CM_ROTATE90CCW:
1474                    docViewer->setRotation( docViewer->getRotation() - 90 );
1475                    return (MRESULT)FALSE;
1476
1477                case CM_NAVPANE:
1478                    {
1479                        Lucide::showIndex = !Lucide::showIndex;
1480                        Lucide::checkNavpane();
1481                        WinSendMsg( hVertSplitter, SBM_SETSPLITTERPOS,
1482                            MPFROMSHORT( Lucide::showIndex ? Lucide::splitterPos : 0 ), MPVOID );
1483                        if ( !Lucide::showIndex ) {
1484                            Lucide::focusDocview();
1485                        }
1486                    }
1487                    return (MRESULT)FALSE;
1488
1489                case CM_FULLSCREEN:
1490                    Lucide::toggleFullscreen();
1491                    return (MRESULT)FALSE;
1492
1493                case CM_PRESENTATION:
1494                    Lucide::togglePresentation();
1495                    return (MRESULT)FALSE;
1496
1497                case CM_PRODINFO:
1498                    AboutBox( hWndFrame );
1499                    return (MRESULT)FALSE;
1500
1501                case CM_MINIMIZE:
1502                    Lucide::cmdMinimize();
1503                    return (MRESULT)FALSE;
1504
1505                case CM_TOPRESENTATION:
1506                    Lucide::cmdSwitchToPresentation();
1507                    return (MRESULT)FALSE;
1508
1509                case CM_SWITCHWINDOW:
1510                    Lucide::cmdSwitchWindow();
1511                    return (MRESULT)FALSE;
1512            }
1513        }
1514        break;
1515
1516        case WM_CLOSE:
1517            if ( !Lucide::closeDocument() )
1518                return (MRESULT)FALSE;
1519        break;
1520    }
1521    return pOldSplProc( hwnd, msg, mp1, mp2 );
1522}
1523
1524
1525char deffont[] = "9.WarpSans";
1526int deffontlen = sizeof( deffont );
1527
1528__declspec(dllexport) _System APIRET APIENTRY LucideMain( int argc, char *argv[] )
1529{
1530    HMQ   hmq;
1531    QMSG  qmsg;
1532    hab = WinInitialize( 0 );
1533    hmq = WinCreateMsgQueue( hab, 0 );
1534
1535    loadLang();
1536
1537    settings = new LuSettings;
1538    settings->load();
1539
1540    pluginMan = new PluginManager;
1541
1542    InitPMSplitterClass( hab );
1543    InitPMToolbarClass( hab );
1544
1545    ULONG ulFrameFlags = FCF_TITLEBAR | FCF_SIZEBORDER | FCF_SYSMENU |
1546                         FCF_MINMAX | FCF_TASKLIST | FCF_NOBYTEALIGN | FCF_ICON;
1547    title = newstrdupL( MSGS_MAIN_WIN_TITLE );
1548    hWndFrame = WinCreateStdWindow( HWND_DESKTOP, 0, &ulFrameFlags, NULL, title,
1549                                    WS_SYNCPAINT|WS_VISIBLE, _hmod, IDI_MAIN_ICON, NULL );
1550    pOldFrameProc = WinSubclassWindow( hWndFrame, frameProc );
1551
1552    hFrameSysmenu  = WinWindowFromID( hWndFrame, FID_SYSMENU );
1553    hFrameTitlebar = WinWindowFromID( hWndFrame, FID_TITLEBAR );
1554    hFrameMinMax   = WinWindowFromID( hWndFrame, FID_MINMAX );
1555    WinSetAccelTable( hab, WinLoadAccelTable( hab, _hmod, IDA_MAINACCEL ), hWndFrame );
1556    hWndMenu = WinLoadMenu( hWndFrame, _hmod, IDM_MAINMENU );
1557    localizeMenu( hWndMenu );
1558    WinSetWindowUShort( hWndMenu, QWS_ID, FID_MENU );
1559
1560    // Vertical splitter and his windows - Index and Document view
1561    hVertSplitter = WinCreateWindow( hWndFrame, WC_ER_SPLITTER, "",
1562                                     WS_VISIBLE | SBS_VSPLIT,
1563                                     0, 0, 0, 0, hWndFrame, HWND_TOP,
1564                                     ID_SPLITTER, NULL, NULL );
1565
1566    indexWin = new IndexWindow( hWndFrame );
1567
1568    DocumentViewer::registerClass();
1569
1570    docViewer = new DocumentViewer( hWndFrame );
1571
1572    WinSendMsg( hVertSplitter, SBM_SETWINDOWS,
1573                MPFROMHWND( indexWin->getHWND() ), MPFROMHWND( docViewer->getFrameHWND() ) );
1574
1575    // Horizontal splitter and its windows - Toolbar and Vertical splitter
1576    // Horizontal splitter is client window
1577    hHorizSplitter = WinCreateWindow( hWndFrame, WC_ER_SPLITTER, "",
1578                                      WS_VISIBLE | SBS_HSPLIT | SBS_SECONDFIXED,
1579                                      0, 0, 0, 0, hWndFrame, HWND_TOP,
1580                                      FID_CLIENT, NULL, NULL );
1581    pOldSplProc = WinSubclassWindow( hHorizSplitter, splProc );
1582
1583    hToolBar = createToolbar( hWndFrame );
1584
1585    WinSendMsg( hHorizSplitter, SBM_SETWINDOWS,
1586                MPFROMHWND( hVertSplitter ), MPFROMHWND( hToolBar ) );
1587    // ᅵᅵ⠭ᅵᅵᅵᅵᅵ 䚪ᅵ஢ᅵᅵᅵᅵ ࠧᅵᅵᅵ ᅵᅵᅵ ᅵ㫡ᅵᅵ
1588    WinSendMsg( hHorizSplitter, SBM_SETFIXEDSIZE,
1589                MPFROMSHORT( DEFAULT_PICTSIZE + TOOLBAR_HEIGHT_ADD ), MPVOID );
1590
1591    Lucide::checkMenus( true );
1592    Lucide::setPageLayout( settings->layout );
1593    Lucide::setZoom( settings->zoom );
1594
1595    findDlg = new FindDlg( hWndFrame );
1596    recent  = new RecentFiles( hWndMenu );
1597
1598    Lucide::restorePosition();
1599
1600    Lucide::focusDocview();
1601
1602    if ( argc > 1 ) {
1603        Lucide::loadDocument( argv[1] );
1604    }
1605
1606    Lucide::checkNavpane();
1607    initPipeMon( hWndFrame );
1608
1609    // Messsage loop
1610    while ( WinGetMsg( hab, &qmsg, 0, 0, 0 ) ) {
1611        WinDispatchMsg( hab, &qmsg );
1612    }
1613
1614    Lucide::savePosition();
1615
1616    WinDestroyWindow( hWndFrame );
1617
1618    recent->save();
1619
1620    Lucide::closeDocument( true );
1621    delete docViewer;
1622    delete indexWin;
1623
1624    // must be freed _after_ document
1625    delete pluginMan;
1626
1627    delete findDlg;
1628    delete recent;
1629    delete title;
1630    delete settings;
1631    unInitPipeMon();
1632
1633    WinDestroyMsgQueue( hmq );
1634    WinTerminate( hab );
1635    return 0;
1636}
1637
Note: See TracBrowser for help on using the repository browser.