source: trunk/Lucide/SOURCE/gui/indexWindow.cpp @ 242

Last change on this file since 242 was 211, checked in by Eugene Romanenko, 14 years ago

TAB key switch between navigation pane and document (closes #112, #123)

File size: 9.9 KB
Line 
1/* ***** BEGIN LICENSE BLOCK *****
2 * Version: CDDL 1.0/LGPL 2.1
3 *
4 * The contents of this file are subject to the COMMON DEVELOPMENT AND
5 * DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use
6 * this file except in compliance with the License. You may obtain a copy of
7 * the License at http://www.sun.com/cddl/
8 *
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
13 *
14 * The Initial Developer of the Original Code is
15 * Eugene Romanenko, netlabs.org.
16 * Portions created by the Initial Developer are Copyright (C) 2006
17 * the Initial Developer. All Rights Reserved.
18 *
19 * Contributor(s):
20 *
21 * Alternatively, the contents of this file may be used under the terms of
22 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
23 * in which case the provisions of the LGPL are applicable instead of those
24 * above. If you wish to allow use of your version of this file only under the
25 * terms of the LGPL, and not to allow others to use your version of this file
26 * under the terms of the CDDL, indicate your decision by deleting the
27 * provisions above and replace them with the notice and other provisions
28 * required by the LGPL. If you do not delete the provisions above, a recipient
29 * may use your version of this file under the terms of any one of the CDDL
30 * or the LGPL.
31 *
32 * ***** END LICENSE BLOCK ***** */
33
34
35#define INCL_WIN
36#include <os2.h>
37
38#include <stdio.h>
39
40#include <ludoc.xh>
41#include "lucide.h"
42#include "indexWindow.h"
43#include "luutils.h"
44#include "tb_spl.h"
45#include "messages.h"
46
47
48#define ID_BAR      1
49#define ID_INDEX    2
50
51
52// IndexWindow constructor
53IndexWindow::IndexWindow( HWND hWndFrame )
54{
55    hMainFrame  = hWndFrame;
56    hWndIndex   = NULLHANDLE;
57    doc         = NULL;
58    totalpages  = 0;
59
60    hWndPanel = WinCreateWindow( hWndFrame, WC_ER_SPLITTER, "",
61                                 WS_VISIBLE | SBS_HSPLIT | SBS_SECONDFIXED,
62                                 0, 0, 0, 0, hWndFrame, HWND_TOP, 0, NULL, NULL );
63    WinSetWindowULong( hWndPanel, QWL_USER, (ULONG)this );
64    pOldPanelProc = WinSubclassWindow( hWndPanel, panelProc );
65
66    // index/thumbs switch will be here
67    hWndBar = WinCreateWindow( hWndFrame, WC_STATIC, NULL,
68                               WS_VISIBLE | SS_TEXT | DT_LEFT | DT_VCENTER,
69                               0, 0, 0, 0, hWndPanel, HWND_TOP, ID_BAR, NULL, NULL );
70    WinSetPresParam( hWndBar, PP_FONTNAMESIZE, deffontlen, deffont );
71    ULONG syscmenu = SYSCLR_MENU;
72    WinSetPresParam( hWndBar, PP_BACKGROUNDCOLORINDEX, sizeof( ULONG ), &syscmenu );
73
74    hWndIndex = WinCreateWindow( hWndFrame, WC_CONTAINER, "",
75                        WS_VISIBLE|CCS_MINIRECORDCORE|CCS_READONLY|CCS_MINIICONS,
76                        0, 0, 0, 0, hWndPanel, HWND_TOP, ID_INDEX, NULL, NULL );
77    WinSetPresParam( hWndIndex, PP_FONTNAMESIZE, deffontlen, deffont );
78
79    WinSendMsg( hWndPanel, SBM_SETWINDOWS,
80                MPFROMHWND( hWndIndex ), MPFROMHWND( hWndBar ) );
81    WinSendMsg( hWndPanel, SBM_SETFIXEDSIZE, MPFROMSHORT( 0 ), MPVOID );
82}
83
84// IndexWindow destructor
85IndexWindow::~IndexWindow()
86{
87    clear( NULL );
88}
89
90
91void IndexWindow::setDocument( LuDocument *_doc )
92{
93    clear( NULL );
94
95    doc = _doc;
96
97    if ( doc == NULL ) {
98        totalpages = 0;
99    }
100    else
101    {
102        totalpages = doc->getPageCount( ev );
103
104        if ( doc->isHaveIndex( ev ) ) {
105            loadIndex();
106        }
107        else {
108            loadPagesList();
109        }
110    }
111}
112
113void IndexWindow::loadIndex()
114{
115    CNRINFO ci;
116    ci.cb = sizeof( CNRINFO );
117    WinSendMsg( hWndIndex, CM_QUERYCNRINFO, MPFROMP( &ci ), MPFROMSHORT( ci.cb ) );
118    ci.flWindowAttr &= ~( CV_NAME | CV_FLOW | CV_TEXT | CV_ICON | CV_TREE );
119    ci.flWindowAttr |= ( CV_TREE | CV_TEXT | CV_MINI | CA_TREELINE );
120    WinSendMsg( hWndIndex, CM_SETCNRINFO, MPFROMP( &ci ), MPFROMLONG( CMA_FLWINDOWATTR ) );
121
122    LuIndexNode *n = doc->getIndex( ev );
123    LuIndexNode *cn = n->getFirstChild( ev );
124    while ( cn != NULL )
125    {
126        addNodes( NULL, cn );
127        cn = n->getNextChild( ev );
128    }
129    delete n;
130}
131
132void IndexWindow::addNodes( TreeRecord *parent, LuIndexNode *n )
133{
134    if ( n == NULL ) {
135        return;
136    }
137
138    LuLink *link = n->getLink( ev );
139
140    RECORDINSERT ri;
141    TreeRecord *pr = (TreeRecord *)WinSendMsg( hWndIndex, CM_ALLOCRECORD,
142       MPFROMLONG( sizeof( TreeRecord ) - sizeof( MINIRECORDCORE ) ), MPFROMSHORT( 1 ) );
143
144    pr->miniRecordCore.cb = sizeof( MINIRECORDCORE );
145    pr->miniRecordCore.flRecordAttr = 0;
146    pr->miniRecordCore.ptlIcon.x = 0;
147    pr->miniRecordCore.ptlIcon.y = 0;
148    pr->miniRecordCore.pszIcon = newstrdup( link->title );
149    pr->miniRecordCore.hptrIcon = NULLHANDLE;
150    pr->page = link->page;
151
152    ri.cb = sizeof( RECORDINSERT );
153    ri.pRecordParent = (PRECORDCORE)parent;
154    ri.pRecordOrder = (PRECORDCORE)CMA_END;
155    ri.zOrder = (USHORT)CMA_TOP;
156    ri.cRecordsInsert = 1;
157    ri.fInvalidateRecord = TRUE;
158    WinSendMsg( hWndIndex, CM_INSERTRECORD, MPFROMP( pr ), MPFROMP( &ri ) );
159
160    LuIndexNode *cn = n->getFirstChild( ev );
161    while ( cn != NULL )
162    {
163        addNodes( pr, cn );
164        cn = n->getNextChild( ev );
165    }
166}
167
168void IndexWindow::loadPagesList()
169{
170    char *msgpage = newstrdupL( MSGS_PAGE );
171    CNRINFO ci;
172    ci.cb = sizeof( CNRINFO );
173    WinSendMsg( hWndIndex, CM_QUERYCNRINFO, MPFROMP( &ci ), MPFROMSHORT( ci.cb ) );
174    ci.flWindowAttr &= ~( CV_NAME | CV_FLOW | CV_TEXT | CV_ICON | CV_TREE );
175    ci.flWindowAttr |= ( CV_TEXT | CV_MINI );
176    WinSendMsg( hWndIndex, CM_SETCNRINFO, MPFROMP( &ci ), MPFROMLONG( CMA_FLWINDOWATTR ) );
177
178    char pgbuf[ 64 ];
179    for ( int i = 0; i < totalpages; i++ )
180    {
181        snprintf( pgbuf, sizeof(pgbuf), "%s %d", msgpage, i + 1 );
182        RECORDINSERT ri;
183        TreeRecord *pr = (TreeRecord *)WinSendMsg( hWndIndex, CM_ALLOCRECORD,
184           MPFROMLONG( sizeof( TreeRecord ) - sizeof( MINIRECORDCORE ) ), MPFROMSHORT( 1 ) );
185
186        pr->miniRecordCore.cb = sizeof( MINIRECORDCORE );
187        pr->miniRecordCore.flRecordAttr = 0;
188        pr->miniRecordCore.ptlIcon.x = 0;
189        pr->miniRecordCore.ptlIcon.y = 0;
190        pr->miniRecordCore.pszIcon = newstrdup( pgbuf );
191        pr->miniRecordCore.hptrIcon = NULLHANDLE;
192        pr->page = i;
193
194        ri.cb = sizeof( RECORDINSERT );
195        ri.pRecordParent = (PRECORDCORE)NULL;
196        ri.pRecordOrder = (PRECORDCORE)CMA_END;
197        ri.zOrder = (USHORT)CMA_TOP;
198        ri.cRecordsInsert = 1;
199        ri.fInvalidateRecord = TRUE;
200        WinSendMsg( hWndIndex, CM_INSERTRECORD, MPFROMP( pr ), MPFROMP( &ri ) );
201    }
202    delete msgpage;
203}
204
205void IndexWindow::clear( TreeRecord *parent )
206{
207    SHORT atr = ( parent == NULL ) ? CMA_FIRST : CMA_FIRSTCHILD;
208    TreeRecord *precs = (TreeRecord *)WinSendMsg( hWndIndex, CM_QUERYRECORD,
209                            MPFROMP( parent ), MPFROM2SHORT( atr, CMA_ITEMORDER ) );
210    TreeRecord *pr = precs;
211    while ( ( pr != NULL ) && ( (int)pr != -1 ) )
212    {
213        delete pr->miniRecordCore.pszIcon;
214        clear( pr );
215        pr = (TreeRecord *)WinSendMsg( hWndIndex, CM_QUERYRECORD,
216                                MPFROMP( pr ), MPFROM2SHORT( CMA_NEXT, CMA_ITEMORDER ) );
217    }
218
219    if ( parent == NULL ) {  // top level call
220        WinSendMsg( hWndIndex, CM_REMOVERECORD, MPFROMP( NULL ),
221                                    MPFROM2SHORT( 0, CMA_INVALIDATE ) );
222    }
223}
224
225bool IndexWindow::goToPage( TreeRecord *parent, long page )
226{
227    if ( Lucide::dontSwitchPage ) {
228        return true;
229    }
230
231    SHORT atr = ( parent == NULL ) ? CMA_FIRST : CMA_FIRSTCHILD;
232    TreeRecord *pr = (TreeRecord *)WinSendMsg( hWndIndex, CM_QUERYRECORD,
233                            MPFROMP( parent ), MPFROM2SHORT( atr, CMA_ITEMORDER ) );
234    while ( ( pr != NULL ) && ( (int)pr != -1 ) )
235    {
236        if ( pr->page == page )
237        {
238            if ( parent != NULL ) {
239                WinSendMsg( hWndIndex, CM_EXPANDTREE, MPFROMP( parent ), MPVOID );
240            }
241            WinSendMsg( hWndIndex, CM_SETRECORDEMPHASIS, MPFROMP( pr ),
242                        MPFROM2SHORT( TRUE, CRA_SELECTED | CRA_CURSORED ) );
243            return true;
244        }
245
246        if ( goToPage( pr, page ) ) {
247            return true;
248        }
249
250        pr = (TreeRecord *)WinSendMsg( hWndIndex, CM_QUERYRECORD,
251                                MPFROMP( pr ), MPFROM2SHORT( CMA_NEXT, CMA_ITEMORDER ) );
252    }
253    return false;
254}
255
256
257// static, window procedure
258MRESULT EXPENTRY IndexWindow::panelProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
259{
260    IndexWindow *_this = (IndexWindow *)WinQueryWindowULong( hwnd, QWL_USER );
261
262    switch ( msg )
263    {
264        case WM_CONTROL:
265            switch ( SHORT1FROMMP( mp1 ) )
266            {
267                case ID_INDEX:
268                    switch ( SHORT2FROMMP( mp1 ) )
269                    {
270                        case CN_ENTER:
271                            {
272                                PNOTIFYRECORDENTER re = (PNOTIFYRECORDENTER)mp2;
273                                TreeRecord *tr = (TreeRecord *)re->pRecord;
274                                if ( tr != NULL ) {
275                                    Lucide::dontSwitchPage = true;
276                                    Lucide::goToPage( tr->page );
277                                    Lucide::dontSwitchPage = false;
278                                }
279                            }
280                            break;
281                    }
282                    break;
283            }
284            break;
285           
286        case WM_FOCUSCHANGE:
287            if ( SHORT1FROMMP( mp2 ) ) {
288                Lucide::activeWindow = AwIndex;
289            }
290            break;
291    }
292
293    return _this->pOldPanelProc( hwnd, msg, mp1, mp2 );
294}
295
296
Note: See TracBrowser for help on using the repository browser.