1 | /* ***** BEGIN LICENSE BLOCK ***** |
---|
2 | * Version: CDDL 1.0/LGPL 2.1 |
---|
3 | * |
---|
4 | * The contents of this file are subject to the COMMON DEVELOPMENT AND |
---|
5 | * DISTRIBUTION LICENSE (CDDL) Version 1.0 (the "License"); you may not use |
---|
6 | * this file except in compliance with the License. You may obtain a copy of |
---|
7 | * the License at http://www.sun.com/cddl/ |
---|
8 | * |
---|
9 | * Software distributed under the License is distributed on an "AS IS" basis, |
---|
10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
---|
11 | * for the specific language governing rights and limitations under the |
---|
12 | * License. |
---|
13 | * |
---|
14 | * The Initial Developer of the Original Code is |
---|
15 | * Eugene Romanenko, netlabs.org. |
---|
16 | * Portions created by the Initial Developer are Copyright (C) 2006 |
---|
17 | * the Initial Developer. All Rights Reserved. |
---|
18 | * |
---|
19 | * Contributor(s): |
---|
20 | * |
---|
21 | * Alternatively, the contents of this file may be used under the terms of |
---|
22 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
---|
23 | * in which case the provisions of the LGPL are applicable instead of those |
---|
24 | * above. If you wish to allow use of your version of this file only under the |
---|
25 | * terms of the LGPL, and not to allow others to use your version of this file |
---|
26 | * under the terms of the CDDL, indicate your decision by deleting the |
---|
27 | * provisions above and replace them with the notice and other provisions |
---|
28 | * required by the LGPL. If you do not delete the provisions above, a recipient |
---|
29 | * may use your version of this file under the terms of any one of the CDDL |
---|
30 | * or the LGPL. |
---|
31 | * |
---|
32 | * ***** END LICENSE BLOCK ***** */ |
---|
33 | |
---|
34 | |
---|
35 | #define INCL_DOS |
---|
36 | #define INCL_WIN |
---|
37 | #define INCL_GPI |
---|
38 | #include <os2.h> |
---|
39 | |
---|
40 | #include <string> |
---|
41 | #include <process.h> |
---|
42 | #include <stdio.h> |
---|
43 | #include <ctype.h> |
---|
44 | |
---|
45 | #include <ludoc.xh> |
---|
46 | #include "lucide.h" |
---|
47 | #include "docViewer.h" |
---|
48 | #include "progressDlg.h" |
---|
49 | #include "pluginman.h" |
---|
50 | #include "luutils.h" |
---|
51 | #include "lucide_res.h" |
---|
52 | #include "messages.h" |
---|
53 | |
---|
54 | |
---|
55 | // OpenWatcom headers doesn't have GpiDrawBits() declaration |
---|
56 | extern "C" { |
---|
57 | LONG APIENTRY GpiDrawBits(HPS hps, PVOID pBits, PBITMAPINFO2 pbmiInfoTable, |
---|
58 | LONG lCount, PPOINTL aptlPoints, LONG lRop, ULONG flOptions); |
---|
59 | } |
---|
60 | |
---|
61 | typedef LuDocument_LuRectSequence *PLuRectSequence; |
---|
62 | typedef LuDocument_LuLinkMapSequence *PLuLinkMapSequence; |
---|
63 | |
---|
64 | #define LINE_HEIGHT 16 |
---|
65 | #define BORDER_COLOR 0x909090L |
---|
66 | #define PAGEBACK_COLOR 0xFFFFFFL |
---|
67 | #define VERT_SPACE 2 |
---|
68 | |
---|
69 | // DocumentViewer constructor |
---|
70 | DocumentViewer::DocumentViewer( HWND hWndFrame ) |
---|
71 | { |
---|
72 | hMainFrame = hWndFrame; |
---|
73 | sHscrollMax = 0; |
---|
74 | sVscrollMax = 0; |
---|
75 | sHscrollPos = 0; |
---|
76 | sVscrollPos = 0; |
---|
77 | sVscrollInc = 0; |
---|
78 | sHscrollInc = 0; |
---|
79 | cxClient = 0; |
---|
80 | cyClient = 0; |
---|
81 | hWndDoc = NULLHANDLE; |
---|
82 | doc = NULL; |
---|
83 | totalpages = 0; |
---|
84 | currentpage = 0; |
---|
85 | hpsBuffer = NULLHANDLE; |
---|
86 | hdcBuffer = NULLHANDLE; |
---|
87 | width = 0; |
---|
88 | height = 0; |
---|
89 | fullwidth = 0; |
---|
90 | fullheight = 0; |
---|
91 | bpp = 0; |
---|
92 | zoom = 1.0; |
---|
93 | realzoom = 1.0; |
---|
94 | zoomMode = false; |
---|
95 | rotation = 0; |
---|
96 | pixbuf = NULL; |
---|
97 | spos_x = 0; |
---|
98 | spos_y = 0; |
---|
99 | progressDlg = new ProgressDlg( hWndFrame ); |
---|
100 | drawareas = NULL; |
---|
101 | drawareaIndex = 0; |
---|
102 | closed = true; |
---|
103 | // continuous view |
---|
104 | continuous = false; |
---|
105 | pagesizes = NULL; |
---|
106 | realVscrollMax = 0; |
---|
107 | VScrollStep = 1; |
---|
108 | WinSetRectEmpty( hab, &savedRcl ); |
---|
109 | drawPS = false; |
---|
110 | // fullscreen |
---|
111 | fullscreen = false; |
---|
112 | // asynch draw |
---|
113 | abortAsynch = false; |
---|
114 | termdraw = false; |
---|
115 | enableAsynchDraw = false; |
---|
116 | DosCreateMutexSem( NULL, &todrawAccess, 0, FALSE ); |
---|
117 | DosCreateEventSem( NULL, &haveDraw, 0, FALSE ); |
---|
118 | // selection |
---|
119 | mousePressed = false; |
---|
120 | selectionStart.x = 0; selectionStart.y = 0; |
---|
121 | selectionEnd.x = 0; selectionEnd.y = 0; |
---|
122 | selection = NULL; |
---|
123 | selrects = NULL; |
---|
124 | // links |
---|
125 | haveLinks = false; |
---|
126 | links = NULL; |
---|
127 | handPtr = WinLoadPointer( HWND_DESKTOP, NULLHANDLE, IDP_HAND ); |
---|
128 | zoomInPtr = WinLoadPointer( HWND_DESKTOP, NULLHANDLE, IDP_ZOOM_IN ); |
---|
129 | zoomOutPtr = WinLoadPointer( HWND_DESKTOP, NULLHANDLE, IDP_ZOOM_OUT ); |
---|
130 | // search |
---|
131 | foundrects = NULL; |
---|
132 | searchString = NULL; |
---|
133 | abortSearch = false; |
---|
134 | |
---|
135 | // create windows |
---|
136 | ULONG dfFlags = FCF_VERTSCROLL | FCF_HORZSCROLL | FCF_NOBYTEALIGN; |
---|
137 | hWndDocFrame = WinCreateStdWindow( hWndFrame, WS_VISIBLE, &dfFlags, NULL, NULL, |
---|
138 | WS_VISIBLE, NULLHANDLE, 0, NULL ); |
---|
139 | WinSetWindowULong( hWndDocFrame, QWL_USER, (ULONG)this ); |
---|
140 | oldFrameProc = WinSubclassWindow( hWndDocFrame, docFrameProc ); |
---|
141 | |
---|
142 | hWndDoc = WinCreateWindow( hWndDocFrame, "er.docview", NULL, |
---|
143 | WS_VISIBLE | WS_TABSTOP, 0, 0, 0, 0, hWndDocFrame, |
---|
144 | HWND_TOP, FID_CLIENT, this, NULL ); |
---|
145 | |
---|
146 | hWndHscroll = WinWindowFromID( hWndDocFrame, FID_HORZSCROLL ); |
---|
147 | hWndVscroll = WinWindowFromID( hWndDocFrame, FID_VERTSCROLL ); |
---|
148 | |
---|
149 | drawThreadId = _beginthread( drawthread, NULL, 262144, this ); |
---|
150 | } |
---|
151 | |
---|
152 | // DocumentViewer destructor |
---|
153 | DocumentViewer::~DocumentViewer() |
---|
154 | { |
---|
155 | termdraw = true; |
---|
156 | abortAsynch = true; |
---|
157 | DosPostEventSem( haveDraw ); |
---|
158 | DosWaitThread( &drawThreadId, DCWW_WAIT ); |
---|
159 | DosCloseMutexSem( todrawAccess ); |
---|
160 | DosCloseEventSem( haveDraw ); |
---|
161 | |
---|
162 | if ( doc != NULL ) { |
---|
163 | freeRects( selrects ); |
---|
164 | freeRects( foundrects ); |
---|
165 | freeLinks(); |
---|
166 | } |
---|
167 | |
---|
168 | WinDestroyPointer( handPtr ); |
---|
169 | WinDestroyPointer( zoomInPtr ); |
---|
170 | WinDestroyPointer( zoomOutPtr ); |
---|
171 | |
---|
172 | if ( ( hpsBuffer != NULLHANDLE ) && ( hdcBuffer != NULLHANDLE ) ) { |
---|
173 | DestroyGraphicsBuffer( hpsBuffer, hdcBuffer ); |
---|
174 | hpsBuffer = hdcBuffer = NULLHANDLE; |
---|
175 | } |
---|
176 | delete pixbuf; |
---|
177 | delete progressDlg; |
---|
178 | delete searchString; |
---|
179 | delete pagesizes; |
---|
180 | delete selection; |
---|
181 | } |
---|
182 | |
---|
183 | |
---|
184 | // static, registration of a window class |
---|
185 | void DocumentViewer::registerClass() |
---|
186 | { |
---|
187 | WinRegisterClass( hab, "er.docview", docViewProc, CS_SIZEREDRAW, sizeof( ULONG ) * 2 ); |
---|
188 | } |
---|
189 | |
---|
190 | // sets the document for viewing |
---|
191 | void DocumentViewer::setDocument( LuDocument *_doc ) |
---|
192 | { |
---|
193 | close(); |
---|
194 | doc = _doc; |
---|
195 | |
---|
196 | if ( doc != NULL ) |
---|
197 | { |
---|
198 | closed = false; |
---|
199 | |
---|
200 | totalpages = doc->getPageCount( ev ); |
---|
201 | bpp = doc->getBpp( ev ); |
---|
202 | if ( !doc->isScalable( ev ) ) { |
---|
203 | zoom = 1; |
---|
204 | } |
---|
205 | haveLinks = doc->isHaveLinks( ev ); |
---|
206 | |
---|
207 | pagesizes = new LuSize[ totalpages ]; |
---|
208 | countPagesizes(); |
---|
209 | adjustSize(); |
---|
210 | |
---|
211 | selrects = new PLuRectSequence[ totalpages ]; |
---|
212 | memset( selrects, 0, sizeof( PLuRectSequence ) * totalpages ); |
---|
213 | |
---|
214 | foundrects = new PLuRectSequence[ totalpages ]; |
---|
215 | memset( foundrects, 0, sizeof( PLuRectSequence ) * totalpages ); |
---|
216 | |
---|
217 | links = new PLuLinkMapSequence[ totalpages ]; |
---|
218 | memset( links, 0, sizeof( PLuLinkMapSequence ) * totalpages ); |
---|
219 | |
---|
220 | selection = new LuRectangle[ totalpages ]; |
---|
221 | memset( selection, 0, sizeof( LuRectangle ) * totalpages ); |
---|
222 | |
---|
223 | drawPS = doc->isRenderIntoPS( ev ); |
---|
224 | if ( drawPS ) { |
---|
225 | enableAsynchDraw = false; |
---|
226 | } |
---|
227 | else { |
---|
228 | enableAsynchDraw = doc->isAsynchRenderingSupported( ev ); |
---|
229 | } |
---|
230 | goToPage( 0 ); |
---|
231 | } |
---|
232 | } |
---|
233 | |
---|
234 | void DocumentViewer::countPagesizes() |
---|
235 | { |
---|
236 | for ( long i = 0; i < totalpages; i++ ) |
---|
237 | { |
---|
238 | doc->getPageSize( ev, i, &pagesizes[i].x, &pagesizes[i].y ); |
---|
239 | if ( isRotated() ) { |
---|
240 | double tmp = pagesizes[i].x; |
---|
241 | pagesizes[i].x = pagesizes[i].y; |
---|
242 | pagesizes[i].y = tmp; |
---|
243 | } |
---|
244 | fullwidth = __max( fullwidth, pagesizes[i].x ); |
---|
245 | fullheight += ( pagesizes[i].y + VERT_SPACE ); |
---|
246 | } |
---|
247 | } |
---|
248 | |
---|
249 | // closes the document |
---|
250 | void DocumentViewer::close() |
---|
251 | { |
---|
252 | if ( closed ) { |
---|
253 | return; |
---|
254 | } |
---|
255 | |
---|
256 | closed = true; |
---|
257 | abortAsynch = true; |
---|
258 | DosRequestMutexSem( todrawAccess, SEM_INDEFINITE_WAIT ); |
---|
259 | |
---|
260 | delete drawareas; |
---|
261 | drawareas = NULL; |
---|
262 | |
---|
263 | delete pagesizes; |
---|
264 | pagesizes = NULL; |
---|
265 | |
---|
266 | delete selection; |
---|
267 | selection = NULL; |
---|
268 | |
---|
269 | freeRects( foundrects ); |
---|
270 | delete foundrects; |
---|
271 | foundrects = NULL; |
---|
272 | |
---|
273 | freeRects( selrects ); |
---|
274 | delete selrects; |
---|
275 | selrects = NULL; |
---|
276 | |
---|
277 | freeLinks(); |
---|
278 | |
---|
279 | doc = NULL; |
---|
280 | totalpages = 0; |
---|
281 | currentpage = 0; |
---|
282 | fullwidth = 0; |
---|
283 | fullheight = 0; |
---|
284 | haveLinks = false; |
---|
285 | |
---|
286 | DosReleaseMutexSem( todrawAccess ); |
---|
287 | } |
---|
288 | |
---|
289 | // sets the page layout |
---|
290 | void DocumentViewer::setPageLayout( PgLayout layout ) |
---|
291 | { |
---|
292 | continuous = ( layout == Continuous ); |
---|
293 | if ( doc != NULL ) { |
---|
294 | long pg = currentpage; |
---|
295 | drawPage(); |
---|
296 | if ( continuous ) { |
---|
297 | goToPage( pg ); |
---|
298 | } |
---|
299 | } |
---|
300 | } |
---|
301 | |
---|
302 | void DocumentViewer::freeRects( LuDocument_LuRectSequence **rects ) |
---|
303 | { |
---|
304 | if ( rects != NULL ) |
---|
305 | { |
---|
306 | for ( long i = 0; i < totalpages; i++ ) { |
---|
307 | if ( rects[ i ] != NULL ) { |
---|
308 | LuDocument::freeRectangles( ev, rects[ i ] ); |
---|
309 | rects[ i ] = NULL; |
---|
310 | } |
---|
311 | } |
---|
312 | } |
---|
313 | } |
---|
314 | |
---|
315 | void DocumentViewer::freeLinks() |
---|
316 | { |
---|
317 | if ( links != NULL ) |
---|
318 | { |
---|
319 | for ( long i = 0; i < totalpages; i++ ) { |
---|
320 | if ( links[ i ] != NULL ) { |
---|
321 | LuDocument::freeLinkMapping( ev, links[ i ] ); |
---|
322 | links[ i ] = NULL; |
---|
323 | } |
---|
324 | } |
---|
325 | |
---|
326 | delete links; |
---|
327 | links = NULL; |
---|
328 | } |
---|
329 | } |
---|
330 | |
---|
331 | |
---|
332 | // switch view to specified page |
---|
333 | void DocumentViewer::goToPage( long page ) |
---|
334 | { |
---|
335 | if ( ( page < 0 ) || ( page >= totalpages ) ) { |
---|
336 | return; |
---|
337 | } |
---|
338 | |
---|
339 | if ( continuous && ( doc != NULL ) ) |
---|
340 | { |
---|
341 | bool needRedraw = ( page == currentpage ); |
---|
342 | double pgpos = pagenumToPos( page ) / VScrollStep; |
---|
343 | vertScroll( hWndDoc, MPFROM2SHORT( pgpos, SB_SLIDERPOSITION ), NULLHANDLE ); |
---|
344 | if ( needRedraw ) { |
---|
345 | drawPage(); |
---|
346 | } |
---|
347 | } |
---|
348 | else |
---|
349 | { |
---|
350 | currentpage = page; |
---|
351 | sVscrollPos = 0; |
---|
352 | if ( doc != NULL ) { |
---|
353 | drawPage(); |
---|
354 | Lucide::checkNavigationMenus(); |
---|
355 | } |
---|
356 | } |
---|
357 | } |
---|
358 | |
---|
359 | // Sets the zoom level |
---|
360 | // _zoom - actual zoom level or: |
---|
361 | // -1 - fit width |
---|
362 | // -2 - fit page |
---|
363 | void DocumentViewer::setZoom( double _zoom ) |
---|
364 | { |
---|
365 | if ( ( _zoom == 0 ) || ( _zoom < -2 ) || ( ( _zoom > 0 ) && ( _zoom < 0.05 ) ) ) { |
---|
366 | return; |
---|
367 | } |
---|
368 | |
---|
369 | if ( doc != NULL ) { |
---|
370 | if ( doc->isScalable( ev ) ) { |
---|
371 | zoom = _zoom; |
---|
372 | drawPage(); |
---|
373 | } |
---|
374 | } |
---|
375 | else { |
---|
376 | zoom = _zoom; |
---|
377 | } |
---|
378 | } |
---|
379 | |
---|
380 | // Sets the rotation |
---|
381 | // rotation may be 0, 90, 180 or 270 degrees |
---|
382 | // -90 will be changed to 270, 360 to 0 |
---|
383 | void DocumentViewer::setRotation( long _rotation ) |
---|
384 | { |
---|
385 | if ( _rotation == -90 ) { |
---|
386 | _rotation = 270; |
---|
387 | } |
---|
388 | if ( _rotation == 360 ) { |
---|
389 | _rotation = 0; |
---|
390 | } |
---|
391 | |
---|
392 | if ( doc != NULL ) |
---|
393 | { |
---|
394 | if ( doc->isRotable( ev ) ) |
---|
395 | { |
---|
396 | rotation = _rotation; |
---|
397 | countPagesizes(); |
---|
398 | drawPage(); |
---|
399 | } |
---|
400 | } |
---|
401 | else { |
---|
402 | rotation = _rotation; |
---|
403 | } |
---|
404 | } |
---|
405 | |
---|
406 | void DocumentViewer::setFullscreen( bool _fullscreen ) |
---|
407 | { |
---|
408 | fullscreen = _fullscreen; |
---|
409 | ULONG ulFrameStyle = WinQueryWindowULong( hWndDocFrame, QWL_STYLE ); |
---|
410 | |
---|
411 | if ( fullscreen ) |
---|
412 | { |
---|
413 | pglSave = getPageLayout(); |
---|
414 | zoomSave = getZoom(); |
---|
415 | setPageLayout( SinglePage ); |
---|
416 | setZoom( -2 ); |
---|
417 | WinSetParent( hWndHscroll, HWND_OBJECT, FALSE ); |
---|
418 | WinSetParent( hWndVscroll, HWND_OBJECT, FALSE ); |
---|
419 | ulFrameStyle &= ~FS_SIZEBORDER; |
---|
420 | } |
---|
421 | else |
---|
422 | { |
---|
423 | setPageLayout( pglSave ); |
---|
424 | setZoom( zoomSave ); |
---|
425 | WinSetParent( hWndHscroll, hWndDocFrame, FALSE ); |
---|
426 | WinSetParent( hWndVscroll, hWndDocFrame, FALSE ); |
---|
427 | ulFrameStyle &= ~FS_SIZEBORDER; |
---|
428 | } |
---|
429 | |
---|
430 | WinSetWindowULong( hWndDocFrame, QWL_STYLE, ulFrameStyle ); |
---|
431 | WinSendMsg( hWndDocFrame, WM_UPDATEFRAME, |
---|
432 | MPFROMLONG( FCF_VERTSCROLL | FCF_HORZSCROLL | FCF_SIZEBORDER ), MPVOID ); |
---|
433 | } |
---|
434 | |
---|
435 | // copy selected text to clipboard |
---|
436 | void DocumentViewer::copyToClipbrd() |
---|
437 | { |
---|
438 | if ( continuous ) |
---|
439 | { |
---|
440 | std::string txt = ""; |
---|
441 | for ( long i = 0; i < totalpages; i++ ) { |
---|
442 | if ( selrects[ i ] != NULL ) { |
---|
443 | txt += doc->getText( ev, i, &(selection[ i ]) ); |
---|
444 | } |
---|
445 | } |
---|
446 | textToClipbrd( hab, txt.c_str() ); |
---|
447 | } |
---|
448 | else { |
---|
449 | char *t = doc->getText( ev, currentpage, &(selection[ currentpage ]) ); |
---|
450 | textToClipbrd( hab, t ); |
---|
451 | } |
---|
452 | } |
---|
453 | |
---|
454 | // select all text (continuous view) or current page (single page view) |
---|
455 | void DocumentViewer::selectAll() |
---|
456 | { |
---|
457 | if ( continuous ) |
---|
458 | { |
---|
459 | for ( long i = 0; i < totalpages; i++ ) |
---|
460 | { |
---|
461 | selection[ i ].x1 = 0; |
---|
462 | selection[ i ].y1 = 0; |
---|
463 | selection[ i ].x2 = pagesizes[ i ].x; |
---|
464 | selection[ i ].y2 = pagesizes[ i ].y; |
---|
465 | LuDocument::freeRectangles( ev, selrects[ i ] ); |
---|
466 | selrects[ i ] = doc->getSelectionRectangles( ev, i, &(selection[i]) ); |
---|
467 | } |
---|
468 | } |
---|
469 | else |
---|
470 | { |
---|
471 | selection[ currentpage ].x1 = 0; |
---|
472 | selection[ currentpage ].y1 = 0; |
---|
473 | selection[ currentpage ].x2 = pagesizes[ currentpage ].x; |
---|
474 | selection[ currentpage ].y2 = pagesizes[ currentpage ].y; |
---|
475 | LuDocument::freeRectangles( ev, selrects[ currentpage ] ); |
---|
476 | selrects[ currentpage ] = doc->getSelectionRectangles( ev, currentpage, &(selection[currentpage]) ); |
---|
477 | } |
---|
478 | |
---|
479 | Lucide::enableCopy( true ); |
---|
480 | WinInvalidateRect( hWndDoc, NULL, FALSE ); |
---|
481 | } |
---|
482 | |
---|
483 | // perform search in document |
---|
484 | void DocumentViewer::searchDocument( const char *_searchString, bool _caseSensitive, |
---|
485 | bool _continueSearch ) |
---|
486 | { |
---|
487 | abortSearch = false; |
---|
488 | if ( !continueSearch ) { |
---|
489 | freeRects( foundrects ); |
---|
490 | } |
---|
491 | |
---|
492 | delete searchString; |
---|
493 | searchString = newstrdup( _searchString ); |
---|
494 | caseSensitive = _caseSensitive; |
---|
495 | continueSearch = _continueSearch; |
---|
496 | |
---|
497 | progressDlg->setBreakFunc( searchabort, this ); |
---|
498 | progressDlg->setText( "" ); |
---|
499 | progressDlg->show( searchthread, this ); |
---|
500 | } |
---|
501 | |
---|
502 | // static method, cancels asynch rendering if abortAsynch is true |
---|
503 | void DocumentViewer::searchabort( void *data ) |
---|
504 | { |
---|
505 | ((DocumentViewer *)data)->abortSearch = true; |
---|
506 | } |
---|
507 | |
---|
508 | // static method, thread for asynchronous searching |
---|
509 | void DocumentViewer::searchthread( void *p ) |
---|
510 | { |
---|
511 | DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MINIMUM, 0 ); |
---|
512 | DocumentViewer *_this = (DocumentViewer *)p; |
---|
513 | |
---|
514 | HAB thab = WinInitialize( 0 ); |
---|
515 | HMQ thmq = WinCreateMsgQueue( thab, 0 ); |
---|
516 | |
---|
517 | long i = _this->currentpage; |
---|
518 | if ( _this->continueSearch && ( _this->currentpage < ( _this->totalpages - 1 ) ) ) { |
---|
519 | i = _this->currentpage + 1; |
---|
520 | } |
---|
521 | |
---|
522 | bool found = false; |
---|
523 | for ( ; i < _this->totalpages; i++ ) |
---|
524 | { |
---|
525 | char *fmt = newstrdupL( FIND_SEARCH_PAGE_OF ); |
---|
526 | char *buf = new char[ 255 ]; |
---|
527 | snprintf( buf, 255, fmt, i + 1, _this->totalpages ); |
---|
528 | _this->progressDlg->setText( buf ); |
---|
529 | delete fmt; |
---|
530 | delete buf; |
---|
531 | |
---|
532 | _this->foundrects[ i ] = _this->doc->searchText( ev, i, |
---|
533 | (char *)_this->searchString, _this->caseSensitive ); |
---|
534 | if ( _this->foundrects[ i ] != NULL ) |
---|
535 | { |
---|
536 | found = true; |
---|
537 | _this->progressDlg->hide(); |
---|
538 | _this->goToPage( i ); |
---|
539 | if ( _this->foundrects[i]->_length > 0 ) { |
---|
540 | RECTL r; |
---|
541 | _this->docPosToWinPos( i, &(_this->foundrects[i]->_buffer[0]), &r ); |
---|
542 | _this->scrollToPos( _this->hWndDoc, NULLHANDLE, r.xLeft, r.yBottom, false ); |
---|
543 | } |
---|
544 | break; |
---|
545 | } |
---|
546 | |
---|
547 | if ( _this->abortSearch ) { |
---|
548 | break; |
---|
549 | } |
---|
550 | } |
---|
551 | _this->progressDlg->hide(); |
---|
552 | |
---|
553 | if ( !found && !_this->abortSearch ) |
---|
554 | { |
---|
555 | char *notfound = newstrdupL( FIND_NOT_FOUND ); |
---|
556 | WinMessageBox( HWND_DESKTOP, _this->hMainFrame, notfound, NULL, |
---|
557 | 1, MB_OK | MB_ICONEXCLAMATION | MB_MOVEABLE ); |
---|
558 | delete notfound; |
---|
559 | } |
---|
560 | |
---|
561 | WinDestroyMsgQueue( thmq ); |
---|
562 | WinTerminate( thab ); |
---|
563 | _endthread(); |
---|
564 | } |
---|
565 | |
---|
566 | // count real zoom level based on specified |
---|
567 | void DocumentViewer::adjustSize() |
---|
568 | { |
---|
569 | if ( doc != NULL ) |
---|
570 | { |
---|
571 | width = pagesizes[ currentpage ].x; |
---|
572 | height = pagesizes[ currentpage ].y; |
---|
573 | |
---|
574 | fullwidth = 0; |
---|
575 | fullheight = 0; |
---|
576 | for ( long i = 0; i < totalpages; i++ ) { |
---|
577 | fullwidth = __max( fullwidth, pagesizes[i].x ); |
---|
578 | fullheight += pagesizes[i].y; |
---|
579 | } |
---|
580 | |
---|
581 | if ( zoom == -1 ) { // fit width |
---|
582 | realzoom = (double)cxClient / ( continuous ? fullwidth : width ); |
---|
583 | } |
---|
584 | else if ( zoom == -2 ) { // fit page |
---|
585 | realzoom = __min( (double)cxClient / width, (double)cyClient / height ); |
---|
586 | } |
---|
587 | else { |
---|
588 | realzoom = zoom; |
---|
589 | } |
---|
590 | width *= realzoom; |
---|
591 | height *= realzoom; |
---|
592 | fullwidth *= realzoom; |
---|
593 | fullheight *= realzoom; |
---|
594 | fullheight += ( VERT_SPACE * totalpages ); |
---|
595 | } |
---|
596 | } |
---|
597 | |
---|
598 | // page redraw |
---|
599 | void DocumentViewer::drawPage() |
---|
600 | { |
---|
601 | if ( !continuous ) |
---|
602 | { |
---|
603 | LuDocument::freeRectangles( ev, selrects[ currentpage ] ); |
---|
604 | selrects[ currentpage ] = NULL; |
---|
605 | |
---|
606 | if ( links != NULL ) { |
---|
607 | if ( ( links[ currentpage ] == NULL ) && haveLinks ) { |
---|
608 | links[ currentpage ] = doc->getLinkMapping( ev, currentpage ); |
---|
609 | } |
---|
610 | } |
---|
611 | |
---|
612 | Lucide::enableCopy( false ); |
---|
613 | } |
---|
614 | WinSendMsg( hWndDoc, WM_SIZE, MPFROM2SHORT( cxClient, cyClient ), |
---|
615 | MPFROM2SHORT( cxClient, cyClient ) ); |
---|
616 | WinInvalidateRect( hWndDoc, NULL, FALSE ); |
---|
617 | } |
---|
618 | |
---|
619 | |
---|
620 | // handles vertical scrolling |
---|
621 | MRESULT DocumentViewer::vertScroll( HWND hwnd, MPARAM mp2, HRGN hrgn ) |
---|
622 | { |
---|
623 | if ( fullscreen ) { |
---|
624 | return ( MRFROMLONG( 0 ) ); |
---|
625 | } |
---|
626 | |
---|
627 | sVscrollInc = 0; |
---|
628 | |
---|
629 | switch ( SHORT2FROMMP( mp2 ) ) |
---|
630 | { |
---|
631 | case SB_LINEUP: |
---|
632 | sVscrollInc = -(__max( LINE_HEIGHT, VScrollStep )); |
---|
633 | break ; |
---|
634 | case SB_LINEDOWN: |
---|
635 | sVscrollInc = __max( LINE_HEIGHT, VScrollStep ); |
---|
636 | break; |
---|
637 | case SB_PAGEUP: |
---|
638 | sVscrollInc = __min( -1, -( cyClient - LINE_HEIGHT ) ); |
---|
639 | break; |
---|
640 | case SB_PAGEDOWN: |
---|
641 | sVscrollInc = __max( 1, cyClient - LINE_HEIGHT ); |
---|
642 | break; |
---|
643 | case SB_SLIDERTRACK: |
---|
644 | case SB_SLIDERPOSITION: |
---|
645 | sVscrollInc = ( SHORT1FROMMP( mp2 ) - sVscrollPos ) * VScrollStep; |
---|
646 | break; |
---|
647 | } |
---|
648 | |
---|
649 | sVscrollInc = __max( -sVscrollPos * VScrollStep, __min( sVscrollInc, |
---|
650 | ( sVscrollMax - sVscrollPos ) * VScrollStep ) ); |
---|
651 | sVscrollInc = ( sVscrollInc / VScrollStep ) * VScrollStep; |
---|
652 | if ( sVscrollInc != 0 ) |
---|
653 | { |
---|
654 | sVscrollPos += (SHORT)( sVscrollInc / VScrollStep ); |
---|
655 | WinScrollWindow( hwnd, 0, sVscrollInc, NULL, NULL, hrgn, NULL, SW_INVALIDATERGN ); |
---|
656 | WinSendMsg( hWndVscroll, SBM_SETPOS, MPFROMSHORT( sVscrollPos ), MPVOID ); |
---|
657 | WinUpdateWindow( hwnd ); |
---|
658 | sVscrollInc = 0; |
---|
659 | } |
---|
660 | return ( MRFROMLONG( 0 ) ); |
---|
661 | } |
---|
662 | |
---|
663 | // handles horizontal scrolling |
---|
664 | MRESULT DocumentViewer::horizScroll( HWND hwnd, MPARAM mp2, HRGN hrgn ) |
---|
665 | { |
---|
666 | if ( fullscreen ) { |
---|
667 | return ( MRFROMLONG( 0 ) ); |
---|
668 | } |
---|
669 | |
---|
670 | sHscrollInc = 0; |
---|
671 | |
---|
672 | switch ( SHORT2FROMMP( mp2 ) ) |
---|
673 | { |
---|
674 | case SB_LINELEFT: |
---|
675 | sHscrollInc = -LINE_HEIGHT; |
---|
676 | break; |
---|
677 | case SB_LINERIGHT: |
---|
678 | sHscrollInc = LINE_HEIGHT; |
---|
679 | break; |
---|
680 | case SB_PAGELEFT: |
---|
681 | sHscrollInc = __min( -1, -( cxClient - LINE_HEIGHT ) ); |
---|
682 | break; |
---|
683 | case SB_PAGERIGHT: |
---|
684 | sHscrollInc = __max( 1, cxClient - LINE_HEIGHT ); |
---|
685 | break; |
---|
686 | case SB_SLIDERTRACK: |
---|
687 | case SB_SLIDERPOSITION: |
---|
688 | sHscrollInc = SHORT1FROMMP( mp2 ) - sHscrollPos; |
---|
689 | break; |
---|
690 | } |
---|
691 | |
---|
692 | sHscrollInc = __max( -sHscrollPos, __min( sHscrollInc, sHscrollMax - sHscrollPos ) ); |
---|
693 | |
---|
694 | if ( sHscrollInc != 0 ) |
---|
695 | { |
---|
696 | sHscrollPos += (SHORT)sHscrollInc; |
---|
697 | WinScrollWindow( hwnd, -sHscrollInc, 0, NULL, NULL, hrgn, NULL, SW_INVALIDATERGN ); |
---|
698 | WinSendMsg( hWndHscroll, SBM_SETPOS, MPFROMSHORT( sHscrollPos ), MPVOID ); |
---|
699 | WinUpdateWindow( hwnd ); |
---|
700 | sHscrollInc = 0; |
---|
701 | } |
---|
702 | return ( MRFROMLONG( 0 ) ); |
---|
703 | } |
---|
704 | |
---|
705 | |
---|
706 | // handles WM_SIZE message |
---|
707 | // creates appropriate hps buffer, sets scrollbars limits |
---|
708 | void DocumentViewer::wmSize( HWND hwnd, MPARAM mp2 ) |
---|
709 | { |
---|
710 | if ( !WinIsWindowShowing( hwnd ) ) { |
---|
711 | return; |
---|
712 | } |
---|
713 | |
---|
714 | cxClient = SHORT1FROMMP( mp2 ); |
---|
715 | cyClient = SHORT2FROMMP( mp2 ); |
---|
716 | |
---|
717 | double relativeScrollPos = ( sVscrollMax == 0 ) ? 0 : |
---|
718 | (double)sVscrollPos / (double)sVscrollMax; |
---|
719 | |
---|
720 | adjustSize(); |
---|
721 | |
---|
722 | if ( ( hpsBuffer != NULLHANDLE ) && ( hdcBuffer != NULLHANDLE ) ) { |
---|
723 | DestroyGraphicsBuffer( hpsBuffer, hdcBuffer ); |
---|
724 | hpsBuffer = hdcBuffer = NULLHANDLE; |
---|
725 | } |
---|
726 | |
---|
727 | HPS hps = WinGetPS( hwnd ); |
---|
728 | RECTL rectl = { 0, 0, cxClient, cyClient }; |
---|
729 | CreateGraphicsBuffer( hab, &rectl, hps, &hpsBuffer, &hdcBuffer ); |
---|
730 | WinReleasePS( hps ); |
---|
731 | |
---|
732 | if ( fullscreen ) |
---|
733 | { |
---|
734 | sHscrollMax = 0; |
---|
735 | sHscrollPos = 0; |
---|
736 | realVscrollMax = 0; |
---|
737 | VScrollStep = 1; |
---|
738 | sVscrollPos = 0; |
---|
739 | } |
---|
740 | else |
---|
741 | { |
---|
742 | sHscrollMax = (SHORT)__max( 0, ( continuous ? fullwidth : width ) - cxClient ); |
---|
743 | sHscrollPos = __min( sHscrollPos, sHscrollMax ); |
---|
744 | |
---|
745 | WinSendMsg( hWndHscroll, SBM_SETSCROLLBAR, |
---|
746 | MPFROMSHORT(sHscrollPos), MPFROM2SHORT(0, sHscrollMax) ); |
---|
747 | WinSendMsg( hWndHscroll, SBM_SETTHUMBSIZE, |
---|
748 | MPFROM2SHORT( cxClient, width ), MPVOID ); |
---|
749 | WinEnableWindow( hWndHscroll, (BOOL)( sHscrollMax != 0 ) ); |
---|
750 | |
---|
751 | VScrollStep = 1; |
---|
752 | if ( continuous ) |
---|
753 | { |
---|
754 | realVscrollMax = __max( 0, fullheight - cyClient ); |
---|
755 | ULONG ssize = realVscrollMax / VScrollStep; |
---|
756 | while ( ssize > 32000 ) { |
---|
757 | VScrollStep += LINE_HEIGHT; |
---|
758 | ssize = realVscrollMax / VScrollStep; |
---|
759 | } |
---|
760 | |
---|
761 | sVscrollMax = (SHORT)ssize; |
---|
762 | if ( realVscrollMax > ( sVscrollMax * VScrollStep ) ) { |
---|
763 | sVscrollMax += 1; |
---|
764 | } |
---|
765 | } |
---|
766 | else { |
---|
767 | realVscrollMax = sVscrollMax = (SHORT)__max( 0, height - cyClient ); |
---|
768 | } |
---|
769 | sVscrollPos = __min( sVscrollPos, sVscrollMax ); |
---|
770 | |
---|
771 | WinSendMsg( hWndVscroll, SBM_SETSCROLLBAR, |
---|
772 | MPFROMSHORT(sVscrollPos), MPFROM2SHORT(0, sVscrollMax) ); |
---|
773 | if ( continuous ) { |
---|
774 | WinSendMsg( hWndVscroll, SBM_SETTHUMBSIZE, |
---|
775 | MPFROM2SHORT( cyClient/VScrollStep, fullheight/VScrollStep ), MPVOID ); |
---|
776 | } |
---|
777 | else { |
---|
778 | WinSendMsg( hWndVscroll, SBM_SETTHUMBSIZE, |
---|
779 | MPFROM2SHORT( cyClient, height ), MPVOID ); |
---|
780 | } |
---|
781 | WinEnableWindow( hWndVscroll, (BOOL)( sVscrollMax != 0 ) ); |
---|
782 | |
---|
783 | SHORT realScrollPos = (SHORT)(sVscrollMax * relativeScrollPos); |
---|
784 | vertScroll( hWndDoc, MPFROM2SHORT( realScrollPos, SB_SLIDERPOSITION ), NULLHANDLE ); |
---|
785 | } |
---|
786 | } |
---|
787 | |
---|
788 | // returns true if subrect inside rect |
---|
789 | inline bool isSubrect( PRECTL rect, PRECTL subrect ) |
---|
790 | { |
---|
791 | return ( ( subrect->xLeft >= rect->xLeft ) && |
---|
792 | ( subrect->yBottom >= rect->yBottom ) && |
---|
793 | ( subrect->xRight <= rect->xRight ) && |
---|
794 | ( subrect->yTop <= rect->yTop ) ); |
---|
795 | } |
---|
796 | |
---|
797 | // static method, cancels asynch rendering if abortAsynch is true |
---|
798 | long _System DocumentViewer::asynchCallbackFnAbort( void *data ) |
---|
799 | { |
---|
800 | return (long)(((DocumentViewer *)data)->abortAsynch); |
---|
801 | } |
---|
802 | |
---|
803 | // static method, draws area during asynch rendering |
---|
804 | long _System DocumentViewer::asynchCallbackFnDraw( void *data ) |
---|
805 | { |
---|
806 | DocumentViewer *_this = (DocumentViewer *)data; |
---|
807 | HPS hps = WinGetPS( _this->hWndDoc ); |
---|
808 | if ( hps != NULLHANDLE ) |
---|
809 | { |
---|
810 | PRECTL drawRect = &((*_this->drawareas)[_this->drawareaIndex].drawrect); |
---|
811 | LONG rclx = drawRect->xRight - drawRect->xLeft; |
---|
812 | LONG rcly = drawRect->yTop - drawRect->yBottom; |
---|
813 | |
---|
814 | POINTL aptlPoints[4]={ drawRect->xLeft, drawRect->yBottom, |
---|
815 | drawRect->xRight-1, drawRect->yTop-1, |
---|
816 | 0, 0, rclx, rcly }; |
---|
817 | |
---|
818 | LONG lRop = ROP_SRCCOPY; |
---|
819 | BITMAPINFO2 pbmi; |
---|
820 | pbmi.cbFix = 16L; |
---|
821 | pbmi.cx = rclx; |
---|
822 | pbmi.cy = rcly; |
---|
823 | pbmi.cPlanes = 1; |
---|
824 | pbmi.cBitCount = _this->bpp * 8; |
---|
825 | GpiDrawBits( hps, _this->pixbuf->getDataPtr( ev ), &pbmi, 4L, |
---|
826 | aptlPoints, lRop, BBO_IGNORE ); |
---|
827 | |
---|
828 | WinReleasePS( hps ); |
---|
829 | } |
---|
830 | return 0; |
---|
831 | } |
---|
832 | |
---|
833 | // static method, thread for asynchronous rendering |
---|
834 | void DocumentViewer::drawthread( void *p ) |
---|
835 | { |
---|
836 | DosSetPriority( PRTYS_THREAD, PRTYC_REGULAR, PRTYD_MINIMUM, 0 ); |
---|
837 | DocumentViewer *_this = (DocumentViewer *)p; |
---|
838 | |
---|
839 | HAB thab = WinInitialize( 0 ); |
---|
840 | HMQ thmq = WinCreateMsgQueue( thab, 0 ); |
---|
841 | |
---|
842 | ULONG postCnt; |
---|
843 | while ( !_this->termdraw ) |
---|
844 | { |
---|
845 | DosWaitEventSem( _this->haveDraw, SEM_INDEFINITE_WAIT ); |
---|
846 | DosResetEventSem( _this->haveDraw, &postCnt ); |
---|
847 | _this->abortAsynch = false; |
---|
848 | |
---|
849 | if ( ( _this->drawareas != NULL ) && ( _this->doc != NULL ) ) |
---|
850 | { |
---|
851 | DosRequestMutexSem( _this->todrawAccess, SEM_INDEFINITE_WAIT ); |
---|
852 | |
---|
853 | for ( _this->drawareaIndex = 0; |
---|
854 | _this->drawareaIndex < _this->drawareas->size(); |
---|
855 | _this->drawareaIndex++ ) |
---|
856 | { |
---|
857 | PageDrawArea *pda = &(*_this->drawareas)[ _this->drawareaIndex ]; |
---|
858 | |
---|
859 | LONG rclx = pda->drawrect.xRight - pda->drawrect.xLeft; |
---|
860 | LONG rcly = pda->drawrect.yTop - pda->drawrect.yBottom; |
---|
861 | _this->pixbuf = new LuPixbuf( ev, rclx, rcly, _this->bpp ); |
---|
862 | _this->doc->renderPageToPixbufAsynch( ev, pda->pagenum, |
---|
863 | pda->startpos.x, pda->startpos.y, rclx, rcly, _this->realzoom, |
---|
864 | _this->rotation, _this->pixbuf, |
---|
865 | asynchCallbackFnDraw, asynchCallbackFnAbort, p ); |
---|
866 | delete _this->pixbuf; |
---|
867 | _this->pixbuf = NULL; |
---|
868 | |
---|
869 | if ( _this->abortAsynch ) { |
---|
870 | break; // TODO: remove completed areas from drawareas |
---|
871 | } |
---|
872 | } |
---|
873 | |
---|
874 | if ( !_this->abortAsynch ) |
---|
875 | { |
---|
876 | HPS hps = WinGetPS( _this->hWndDoc ); |
---|
877 | if ( hps != NULLHANDLE ) { |
---|
878 | for ( int i = 0; i < _this->drawareas->size(); i++ ) |
---|
879 | { |
---|
880 | PageDrawArea *pda = &(*_this->drawareas)[ i ]; |
---|
881 | |
---|
882 | _this->drawSelection( pda->pagenum, hps, &pda->drawrect ); |
---|
883 | _this->drawFound( pda->pagenum, hps, &pda->drawrect ); |
---|
884 | } |
---|
885 | WinReleasePS( hps ); |
---|
886 | } |
---|
887 | WinSetRectEmpty( thab, &_this->savedRcl ); |
---|
888 | delete _this->drawareas; |
---|
889 | _this->drawareas = NULL; |
---|
890 | } |
---|
891 | |
---|
892 | DosReleaseMutexSem( _this->todrawAccess ); |
---|
893 | } |
---|
894 | } |
---|
895 | WinDestroyMsgQueue( thmq ); |
---|
896 | WinTerminate( thab ); |
---|
897 | _endthread(); |
---|
898 | } |
---|
899 | |
---|
900 | // handles WM_PAINT if single-page asynchronous rendering used |
---|
901 | // posts events to drawthread |
---|
902 | void DocumentViewer::wmPaintAsynch( HWND hwnd ) |
---|
903 | { |
---|
904 | LONG xPos = 0, yPos = 0; |
---|
905 | RECTL rclPage = { 0 }; |
---|
906 | RECTL rcl; |
---|
907 | HPS hps = WinBeginPaint( hwnd, 0L, &rcl ); |
---|
908 | GpiCreateLogColorTable( hpsBuffer, 0, LCOLF_RGB, 0, 0, NULL ); |
---|
909 | WinFillRect( hpsBuffer, &rcl, BORDER_COLOR ); |
---|
910 | if ( doc != NULL ) |
---|
911 | { |
---|
912 | if ( width < cxClient ) { |
---|
913 | xPos = ( cxClient - width ) / 2; |
---|
914 | } |
---|
915 | if ( height < cyClient ) { |
---|
916 | yPos = ( cyClient - height ) / 2; |
---|
917 | } |
---|
918 | |
---|
919 | rclPage.xLeft = xPos; |
---|
920 | rclPage.yBottom = yPos; |
---|
921 | rclPage.xRight = width + xPos; |
---|
922 | rclPage.yTop = height + yPos; |
---|
923 | WinFillRect( hpsBuffer, &rclPage, PAGEBACK_COLOR ); |
---|
924 | } |
---|
925 | BlitGraphicsBuffer( hps, hpsBuffer, &rcl ); |
---|
926 | WinEndPaint( hps ); |
---|
927 | |
---|
928 | if ( doc != NULL ) |
---|
929 | { |
---|
930 | RECTL rclDraw = { 0 }; |
---|
931 | if ( WinIntersectRect( hab, &rclDraw, &rcl, &rclPage ) ) |
---|
932 | { |
---|
933 | if ( ( drawareas != NULL ) && ( drawareas->size() > 0 ) ) { |
---|
934 | if ( isSubrect( &((*drawareas)[0].drawrect), &rclDraw ) && |
---|
935 | ( sVscrollInc == 0 ) && ( sHscrollInc == 0 ) ) { |
---|
936 | return; |
---|
937 | } |
---|
938 | } |
---|
939 | |
---|
940 | abortAsynch = true; |
---|
941 | DosRequestMutexSem( todrawAccess, SEM_INDEFINITE_WAIT ); |
---|
942 | |
---|
943 | if ( drawareas == NULL ) { |
---|
944 | drawareas = new DrawAreas; |
---|
945 | } |
---|
946 | if ( drawareas->size() == 0 ) { |
---|
947 | PageDrawArea pda; |
---|
948 | memset( &pda, 0, sizeof( pda ) ); |
---|
949 | pda.pagenum = currentpage; |
---|
950 | drawareas->push_back( pda ); |
---|
951 | } |
---|
952 | |
---|
953 | PageDrawArea *ppda = &((*drawareas)[0]); |
---|
954 | |
---|
955 | if ( !WinIsRectEmpty( hab, &ppda->drawrect ) ) |
---|
956 | { |
---|
957 | if ( sVscrollInc > 0 ) { |
---|
958 | ppda->drawrect.yTop += sVscrollInc; |
---|
959 | } else if ( sVscrollInc < 0 ) { |
---|
960 | ppda->drawrect.yBottom += sVscrollInc; |
---|
961 | } |
---|
962 | if ( sHscrollInc > 0 ) { |
---|
963 | ppda->drawrect.xLeft -= sHscrollInc; |
---|
964 | } else if ( sHscrollInc < 0 ) { |
---|
965 | ppda->drawrect.xRight -= sHscrollInc; |
---|
966 | } |
---|
967 | } |
---|
968 | WinUnionRect( hab, &ppda->drawrect, &ppda->drawrect, &rclDraw ); |
---|
969 | ppda->startpos.x = sHscrollPos + ppda->drawrect.xLeft - xPos; |
---|
970 | ppda->startpos.y = ( yPos > 0 ) ? rclPage.yTop - ppda->drawrect.yTop : |
---|
971 | ( cyClient - ppda->drawrect.yTop ) + sVscrollPos; |
---|
972 | |
---|
973 | DosReleaseMutexSem( todrawAccess ); |
---|
974 | DosPostEventSem( haveDraw ); |
---|
975 | } |
---|
976 | } |
---|
977 | } |
---|
978 | |
---|
979 | |
---|
980 | // handles WM_PAINT if continuous asynchronous rendering used |
---|
981 | void DocumentViewer::wmPaintContAsynch( HWND hwnd ) |
---|
982 | { |
---|
983 | RECTL rcl, rclWin, rclDraw = { 0 }; |
---|
984 | HPS hps = WinBeginPaint( hwnd, 0L, &rcl ); |
---|
985 | GpiCreateLogColorTable( hpsBuffer, 0, LCOLF_RGB, 0, 0, NULL ); |
---|
986 | WinFillRect( hpsBuffer, &rcl, BORDER_COLOR ); |
---|
987 | |
---|
988 | if ( doc != NULL ) |
---|
989 | { |
---|
990 | long foundpage = -1; |
---|
991 | double pageRest; |
---|
992 | for ( LONG i = rcl.yTop; i >= rcl.yBottom; i-- ) |
---|
993 | { |
---|
994 | pageRest = 0; |
---|
995 | long pg = posToPagenum( i, &pageRest ); |
---|
996 | if ( ( pg != foundpage ) && ( pg != -1 ) ) |
---|
997 | { |
---|
998 | RECTL rclPage = { 0 }; |
---|
999 | LuRectangle lr = { 0, 0, |
---|
1000 | isRotated() ? (pagesizes[ pg ].y - 1) : (pagesizes[ pg ].x - 1), |
---|
1001 | isRotated() ? (pagesizes[ pg ].x - 1) : (pagesizes[ pg ].y - 1) }; |
---|
1002 | docPosToWinPos( pg, &lr, &rclPage ); |
---|
1003 | WinFillRect( hpsBuffer, &rclPage, PAGEBACK_COLOR ); |
---|
1004 | foundpage = pg; |
---|
1005 | i -= pageRest; |
---|
1006 | } |
---|
1007 | } |
---|
1008 | } |
---|
1009 | |
---|
1010 | BlitGraphicsBuffer( hps, hpsBuffer, &rcl ); |
---|
1011 | WinEndPaint( hps ); |
---|
1012 | |
---|
1013 | if ( doc != NULL ) |
---|
1014 | { |
---|
1015 | if ( isSubrect( &savedRcl, &rcl ) && ( sVscrollInc == 0 ) && ( sHscrollInc == 0 ) ) { |
---|
1016 | return; |
---|
1017 | } |
---|
1018 | |
---|
1019 | abortAsynch = true; |
---|
1020 | DosRequestMutexSem( todrawAccess, SEM_INDEFINITE_WAIT ); |
---|
1021 | |
---|
1022 | WinQueryWindowRect( hwnd, &rclWin ); |
---|
1023 | WinUnionRect( hab, &rcl, &rcl, &savedRcl ); |
---|
1024 | |
---|
1025 | if ( sVscrollInc > 0 ) { |
---|
1026 | rcl.yTop += sVscrollInc; |
---|
1027 | } else if ( sVscrollInc < 0 ) { |
---|
1028 | rcl.yBottom += sVscrollInc; |
---|
1029 | } |
---|
1030 | if ( sHscrollInc > 0 ) { |
---|
1031 | rcl.xLeft -= sHscrollInc; |
---|
1032 | } else if ( sHscrollInc < 0 ) { |
---|
1033 | rcl.xRight -= sHscrollInc; |
---|
1034 | } |
---|
1035 | |
---|
1036 | WinIntersectRect( hab, &rclDraw, &rcl, &rclWin ); |
---|
1037 | WinCopyRect( hab, &rcl, &rclDraw ); |
---|
1038 | WinCopyRect( hab, &savedRcl, &rcl ); |
---|
1039 | |
---|
1040 | delete drawareas; |
---|
1041 | drawareas = findDrawAreas( &rcl ); |
---|
1042 | |
---|
1043 | for ( int i = 0; i < drawareas->size(); i++ ) |
---|
1044 | { |
---|
1045 | PageDrawArea *pda = &(*drawareas)[ i ]; |
---|
1046 | |
---|
1047 | // load links for page if not loaded before |
---|
1048 | if ( ( links[ pda->pagenum ] == NULL ) && haveLinks ) { |
---|
1049 | links[ pda->pagenum ] = doc->getLinkMapping( ev, pda->pagenum ); |
---|
1050 | } |
---|
1051 | } |
---|
1052 | DosReleaseMutexSem( todrawAccess ); |
---|
1053 | DosPostEventSem( haveDraw ); |
---|
1054 | |
---|
1055 | determineCurrentPage(); |
---|
1056 | } |
---|
1057 | } |
---|
1058 | |
---|
1059 | |
---|
1060 | // handles WM_PAINT if single-page synchronous rendering used |
---|
1061 | void DocumentViewer::wmPaint( HWND hwnd ) |
---|
1062 | { |
---|
1063 | RECTL rcl; |
---|
1064 | HPS hps = WinBeginPaint( hwnd, 0L, &rcl ); |
---|
1065 | GpiCreateLogColorTable( hpsBuffer, 0, LCOLF_RGB, 0, 0, NULL ); |
---|
1066 | WinFillRect( hpsBuffer, &rcl, BORDER_COLOR ); |
---|
1067 | |
---|
1068 | if ( doc != NULL ) |
---|
1069 | { |
---|
1070 | LONG xPos = 0, yPos = 0; |
---|
1071 | if ( width < cxClient ) { |
---|
1072 | xPos = ( cxClient - width ) / 2; |
---|
1073 | } |
---|
1074 | if ( height < cyClient ) { |
---|
1075 | yPos = ( cyClient - height ) / 2; |
---|
1076 | } |
---|
1077 | |
---|
1078 | RECTL rclPage = { xPos, yPos, width + xPos, height + yPos }; |
---|
1079 | RECTL rclDraw = { 0 }; |
---|
1080 | if ( WinIntersectRect( hab, &rclDraw, &rcl, &rclPage ) ) |
---|
1081 | { |
---|
1082 | spos_x = sHscrollPos + rclDraw.xLeft - xPos; |
---|
1083 | spos_y = ( yPos > 0 ) ? rclPage.yTop - rclDraw.yTop : (cyClient - rclDraw.yTop) + sVscrollPos; |
---|
1084 | LONG rclx = rclDraw.xRight - rclDraw.xLeft; |
---|
1085 | LONG rcly = rclDraw.yTop - rclDraw.yBottom; |
---|
1086 | |
---|
1087 | if ( drawPS ) |
---|
1088 | { |
---|
1089 | doc->renderPageToPS( ev, currentpage, spos_x, spos_y, rclx, rcly, |
---|
1090 | realzoom, rotation, hpsBuffer, &rclDraw ); |
---|
1091 | } |
---|
1092 | else |
---|
1093 | { |
---|
1094 | pixbuf = new LuPixbuf( ev, rclx, rcly, bpp ); |
---|
1095 | POINTL aptlPoints[4]={ rclDraw.xLeft, rclDraw.yBottom, |
---|
1096 | rclDraw.xRight-1, rclDraw.yTop-1, |
---|
1097 | 0, 0, rclx, rcly }; |
---|
1098 | |
---|
1099 | doc->renderPageToPixbuf( ev, currentpage, spos_x, spos_y, |
---|
1100 | rclx, rcly, realzoom, rotation, pixbuf ); |
---|
1101 | LONG lRop = ROP_SRCCOPY; |
---|
1102 | BITMAPINFO2 pbmi; |
---|
1103 | pbmi.cbFix = 16L; |
---|
1104 | pbmi.cx = rclx; |
---|
1105 | pbmi.cy = rcly; |
---|
1106 | pbmi.cPlanes = 1; |
---|
1107 | pbmi.cBitCount = bpp * 8; |
---|
1108 | GpiDrawBits( hpsBuffer, pixbuf->getDataPtr( ev ), &pbmi, 4L, |
---|
1109 | aptlPoints, lRop, BBO_IGNORE ); |
---|
1110 | delete pixbuf; |
---|
1111 | pixbuf = NULL; |
---|
1112 | } |
---|
1113 | |
---|
1114 | drawSelection( currentpage, hpsBuffer, &rclDraw ); |
---|
1115 | drawFound( currentpage, hpsBuffer, &rclDraw ); |
---|
1116 | } |
---|
1117 | } |
---|
1118 | BlitGraphicsBuffer( hps, hpsBuffer, &rcl ); |
---|
1119 | WinEndPaint( hps ); |
---|
1120 | } |
---|
1121 | |
---|
1122 | |
---|
1123 | // founds number of page at specified vertical position |
---|
1124 | // for continuous view only |
---|
1125 | long DocumentViewer::posToPagenum( LONG yPosWin, double *pageRest ) |
---|
1126 | { |
---|
1127 | double yPos = ( cyClient - yPosWin ) + ( sVscrollPos * VScrollStep ); |
---|
1128 | double pgstart = 0; |
---|
1129 | double pgend = 0; |
---|
1130 | for ( long i = 0; i < totalpages; i++ ) |
---|
1131 | { |
---|
1132 | pgend = pgstart + ( pagesizes[ i ].y * realzoom ); |
---|
1133 | if ( ( yPos >= pgstart ) && ( yPos < pgend ) ) { |
---|
1134 | *pageRest = pgend - yPos; |
---|
1135 | return i; |
---|
1136 | } |
---|
1137 | pgstart = ( pgend + VERT_SPACE ); |
---|
1138 | } |
---|
1139 | return -1; |
---|
1140 | } |
---|
1141 | |
---|
1142 | // founds vertical position of specified |
---|
1143 | // for continuous view only |
---|
1144 | double DocumentViewer::pagenumToPos( long pagenum ) |
---|
1145 | { |
---|
1146 | double ypos = 0; |
---|
1147 | for ( long i = 0; i < pagenum; i++ ) { |
---|
1148 | ypos += pagesizes[ i ].y; |
---|
1149 | } |
---|
1150 | return ( ( ypos * realzoom ) + ( pagenum * VERT_SPACE ) ); |
---|
1151 | } |
---|
1152 | |
---|
1153 | // founds pages and it's areas to draw |
---|
1154 | // for continuous view only |
---|
1155 | DrawAreas *DocumentViewer::findDrawAreas( PRECTL r ) |
---|
1156 | { |
---|
1157 | DrawAreas *areas = new DrawAreas; |
---|
1158 | if ( doc != NULL ) |
---|
1159 | { |
---|
1160 | long foundpage = -1; |
---|
1161 | double pageRest; |
---|
1162 | for ( LONG i = r->yTop; i >= r->yBottom; i-- ) |
---|
1163 | { |
---|
1164 | pageRest = 0; |
---|
1165 | long pg = posToPagenum( i, &pageRest ); |
---|
1166 | if ( ( pg != foundpage ) && ( pg != -1 ) ) |
---|
1167 | { |
---|
1168 | double w = pagesizes[ pg ].x * realzoom; |
---|
1169 | |
---|
1170 | PageDrawArea pda = {0}; |
---|
1171 | pda.pagenum = pg; |
---|
1172 | |
---|
1173 | LONG xPos = 0; |
---|
1174 | if ( w < cxClient ) { |
---|
1175 | xPos = ( cxClient - w ) / 2; |
---|
1176 | } |
---|
1177 | RECTL rclPage = { 0 }; |
---|
1178 | LuRectangle lr = { 0, 0, |
---|
1179 | isRotated() ? (pagesizes[ pg ].y - 1) : (pagesizes[ pg ].x - 1), |
---|
1180 | isRotated() ? (pagesizes[ pg ].x - 1) : (pagesizes[ pg ].y - 1) }; |
---|
1181 | docPosToWinPos( pg, &lr, &rclPage ); |
---|
1182 | if ( WinIntersectRect( hab, &pda.drawrect, r, &rclPage ) ) |
---|
1183 | { |
---|
1184 | pda.startpos.x = sHscrollPos + pda.drawrect.xLeft - xPos; |
---|
1185 | pda.startpos.y = ( pagesizes[ pg ].y * realzoom ) - pageRest; |
---|
1186 | areas->push_back( pda ); |
---|
1187 | } |
---|
1188 | foundpage = pg; |
---|
1189 | i -= pageRest; |
---|
1190 | } |
---|
1191 | } |
---|
1192 | } |
---|
1193 | |
---|
1194 | return areas; |
---|
1195 | } |
---|
1196 | |
---|
1197 | |
---|
1198 | // found current page in continuous view mode. |
---|
1199 | // it's a page which occupes a most larger area in the window. |
---|
1200 | void DocumentViewer::determineCurrentPage() |
---|
1201 | { |
---|
1202 | RECTL rcl = { 0 }; |
---|
1203 | WinQueryWindowRect( hWndDoc, &rcl ); |
---|
1204 | DrawAreas *areas = findDrawAreas( &rcl ); |
---|
1205 | long pg = 0; |
---|
1206 | long sz = 0; |
---|
1207 | for ( int i = 0; i < areas->size(); i++ ) |
---|
1208 | { |
---|
1209 | PageDrawArea *pda = &(*areas)[ i ]; |
---|
1210 | long pgsz = pda->drawrect.yTop - pda->drawrect.yBottom; |
---|
1211 | if ( pgsz > sz ) { |
---|
1212 | pg = pda->pagenum; |
---|
1213 | sz = pgsz; |
---|
1214 | } |
---|
1215 | } |
---|
1216 | delete areas; |
---|
1217 | |
---|
1218 | if ( pg != currentpage ) { |
---|
1219 | currentpage = pg; |
---|
1220 | Lucide::checkNavigationMenus(); |
---|
1221 | } |
---|
1222 | } |
---|
1223 | |
---|
1224 | |
---|
1225 | // handles WM_PAINT if continuous synchronous rendering used |
---|
1226 | void DocumentViewer::wmPaintCont( HWND hwnd ) |
---|
1227 | { |
---|
1228 | RECTL rcl; |
---|
1229 | HPS hps = WinBeginPaint( hwnd, 0L, &rcl ); |
---|
1230 | GpiCreateLogColorTable( hpsBuffer, 0, LCOLF_RGB, 0, 0, NULL ); |
---|
1231 | WinFillRect( hpsBuffer, &rcl, BORDER_COLOR ); |
---|
1232 | |
---|
1233 | if ( doc != NULL ) |
---|
1234 | { |
---|
1235 | delete drawareas; |
---|
1236 | drawareas = findDrawAreas( &rcl ); |
---|
1237 | |
---|
1238 | for ( int i = 0; i < drawareas->size(); i++ ) |
---|
1239 | { |
---|
1240 | PageDrawArea *pda = &(*drawareas)[ i ]; |
---|
1241 | |
---|
1242 | // load links for page if not loaded before |
---|
1243 | if ( ( links[ pda->pagenum ] == NULL ) && haveLinks ) { |
---|
1244 | links[ pda->pagenum ] = doc->getLinkMapping( ev, pda->pagenum ); |
---|
1245 | } |
---|
1246 | |
---|
1247 | spos_x = pda->startpos.x; |
---|
1248 | spos_y = pda->startpos.y; |
---|
1249 | LONG rclx = pda->drawrect.xRight - pda->drawrect.xLeft; |
---|
1250 | LONG rcly = pda->drawrect.yTop - pda->drawrect.yBottom; |
---|
1251 | |
---|
1252 | if ( drawPS ) |
---|
1253 | { |
---|
1254 | doc->renderPageToPS( ev, pda->pagenum, spos_x, spos_y, rclx, rcly, |
---|
1255 | realzoom, rotation, hpsBuffer, &(pda->drawrect) ); |
---|
1256 | } |
---|
1257 | else |
---|
1258 | { |
---|
1259 | pixbuf = new LuPixbuf( ev, rclx, rcly, bpp ); |
---|
1260 | POINTL aptlPoints[4]={ pda->drawrect.xLeft, pda->drawrect.yBottom, |
---|
1261 | pda->drawrect.xRight-1, pda->drawrect.yTop-1, |
---|
1262 | 0, 0, rclx, rcly }; |
---|
1263 | doc->renderPageToPixbuf( ev, pda->pagenum, spos_x, spos_y, |
---|
1264 | rclx, rcly, realzoom, rotation, pixbuf ); |
---|
1265 | LONG lRop = ROP_SRCCOPY; |
---|
1266 | BITMAPINFO2 pbmi; |
---|
1267 | pbmi.cbFix = 16L; |
---|
1268 | pbmi.cx = rclx; |
---|
1269 | pbmi.cy = rcly; |
---|
1270 | pbmi.cPlanes = 1; |
---|
1271 | pbmi.cBitCount = bpp * 8; |
---|
1272 | GpiDrawBits( hpsBuffer, pixbuf->getDataPtr( ev ), &pbmi, 4L, |
---|
1273 | aptlPoints, lRop, BBO_IGNORE ); |
---|
1274 | delete pixbuf; |
---|
1275 | pixbuf = NULL; |
---|
1276 | } |
---|
1277 | |
---|
1278 | drawSelection( pda->pagenum, hpsBuffer, &pda->drawrect ); |
---|
1279 | drawFound( pda->pagenum, hpsBuffer, &pda->drawrect ); |
---|
1280 | } |
---|
1281 | delete drawareas; |
---|
1282 | drawareas = NULL; |
---|
1283 | } |
---|
1284 | BlitGraphicsBuffer( hps, hpsBuffer, &rcl ); |
---|
1285 | WinEndPaint( hps ); |
---|
1286 | |
---|
1287 | if ( doc != NULL ) { |
---|
1288 | determineCurrentPage(); |
---|
1289 | } |
---|
1290 | } |
---|
1291 | |
---|
1292 | |
---|
1293 | // Rotates document rectangle |
---|
1294 | void DocumentViewer::rotateRectangle( long pagenum, LuRectangle *r ) |
---|
1295 | { |
---|
1296 | double tmp_x1 = r->x1; |
---|
1297 | double tmp_y1 = r->y1; |
---|
1298 | double tmp_x2 = r->x2; |
---|
1299 | double tmp_y2 = r->y2; |
---|
1300 | |
---|
1301 | double w = pagesizes[ pagenum ].x; |
---|
1302 | double h = pagesizes[ pagenum ].y; |
---|
1303 | |
---|
1304 | if ( rotation == 90 ) { |
---|
1305 | r->x1 = tmp_y1; |
---|
1306 | r->y1 = w - tmp_x1; |
---|
1307 | r->x2 = tmp_y2; |
---|
1308 | r->y2 = w - tmp_x2; |
---|
1309 | } |
---|
1310 | else if ( rotation == 180 ) |
---|
1311 | { |
---|
1312 | r->x1 = w - tmp_x2; |
---|
1313 | r->y1 = h - tmp_y2; |
---|
1314 | r->x2 = w - tmp_x1; |
---|
1315 | r->y2 = h - tmp_y1; |
---|
1316 | } |
---|
1317 | else if ( rotation == 270 ) |
---|
1318 | { |
---|
1319 | r->x1 = h - tmp_y1; |
---|
1320 | r->y1 = tmp_x1; |
---|
1321 | r->x2 = h - tmp_y2; |
---|
1322 | r->y2 = tmp_x2; |
---|
1323 | } |
---|
1324 | |
---|
1325 | if ( r->x1 > r->x2 ) { |
---|
1326 | double tmp = r->x1; |
---|
1327 | r->x1 = r->x2; |
---|
1328 | r->x2 = tmp; |
---|
1329 | } |
---|
1330 | |
---|
1331 | if ( r->y1 > r->y2 ) { |
---|
1332 | double tmp = r->y1; |
---|
1333 | r->y1 = r->y2; |
---|
1334 | r->y2 = tmp; |
---|
1335 | } |
---|
1336 | } |
---|
1337 | |
---|
1338 | // converts window position to document position |
---|
1339 | // single page mode only |
---|
1340 | void DocumentViewer::winPosToDocPos( PPOINTL startpoint, PPOINTL endpoint, LuRectangle *r ) |
---|
1341 | { |
---|
1342 | LONG sx = startpoint->x; |
---|
1343 | LONG sy = startpoint->y; |
---|
1344 | LONG ex = endpoint->x; |
---|
1345 | LONG ey = endpoint->y; |
---|
1346 | if ( width < cxClient ) { |
---|
1347 | LONG xPos = ( cxClient - width ) / 2; |
---|
1348 | sx -= xPos; |
---|
1349 | ex -= xPos; |
---|
1350 | } |
---|
1351 | if ( height < cyClient ) { |
---|
1352 | LONG yPos = ( cyClient - height ) / 2; |
---|
1353 | sy += yPos; |
---|
1354 | ey += yPos; |
---|
1355 | } |
---|
1356 | |
---|
1357 | r->x1 = ( sx + sHscrollPos ) / realzoom; |
---|
1358 | r->y1 = ( ( cyClient - sy ) + sVscrollPos ) / realzoom; |
---|
1359 | r->x2 = ( ex + sHscrollPos ) / realzoom; |
---|
1360 | r->y2 = ( ( cyClient - ey ) + sVscrollPos ) / realzoom; |
---|
1361 | |
---|
1362 | rotateRectangle( currentpage, r ); |
---|
1363 | } |
---|
1364 | |
---|
1365 | // converts window position to document position |
---|
1366 | // continuous view mode only |
---|
1367 | void DocumentViewer::winPosToDocPos( PageDrawArea *pda, LuRectangle *r ) |
---|
1368 | { |
---|
1369 | LONG sx = pda->drawrect.xLeft; |
---|
1370 | LONG ex = pda->drawrect.xRight; |
---|
1371 | double w = pagesizes[ pda->pagenum ].x * realzoom; |
---|
1372 | if ( w < cxClient ) { |
---|
1373 | LONG xPos = ( cxClient - w ) / 2; |
---|
1374 | sx -= xPos; |
---|
1375 | ex -= xPos; |
---|
1376 | } |
---|
1377 | |
---|
1378 | r->x1 = ( sHscrollPos + sx ) / realzoom;; |
---|
1379 | r->y1 = pda->startpos.y / realzoom; |
---|
1380 | r->x2 = ( ( ex - sx ) / realzoom ) + r->x1; |
---|
1381 | r->y2 = ( ( pda->drawrect.yTop - pda->drawrect.yBottom ) / realzoom ) + r->y1; |
---|
1382 | |
---|
1383 | rotateRectangle( pda->pagenum, r ); |
---|
1384 | } |
---|
1385 | |
---|
1386 | // converts document position to window position |
---|
1387 | void DocumentViewer::docPosToWinPos( long pagenum, LuRectangle *r, PRECTL rcl ) |
---|
1388 | { |
---|
1389 | double yplus = continuous ? pagenumToPos( pagenum ) : 0; |
---|
1390 | double w = pagesizes[ pagenum ].x; |
---|
1391 | double h = pagesizes[ pagenum ].y; |
---|
1392 | |
---|
1393 | double tmp_x1 = r->x1; |
---|
1394 | double tmp_y1 = r->y1; |
---|
1395 | double tmp_x2 = r->x2; |
---|
1396 | double tmp_y2 = r->y2; |
---|
1397 | |
---|
1398 | if ( rotation == 90 ) |
---|
1399 | { |
---|
1400 | tmp_x1 = w - r->y2; |
---|
1401 | tmp_y1 = r->x1; |
---|
1402 | tmp_x2 = w - r->y1; |
---|
1403 | tmp_y2 = r->x2; |
---|
1404 | } |
---|
1405 | else if ( rotation == 180 ) |
---|
1406 | { |
---|
1407 | tmp_x1 = w - r->x2; |
---|
1408 | tmp_y1 = h - r->y2; |
---|
1409 | tmp_x2 = w - r->x1; |
---|
1410 | tmp_y2 = h - r->y1; |
---|
1411 | } |
---|
1412 | else if ( rotation == 270 ) |
---|
1413 | { |
---|
1414 | tmp_x1 = r->y1; |
---|
1415 | tmp_y1 = h - r->x2; |
---|
1416 | tmp_x2 = r->y2; |
---|
1417 | tmp_y2 = h - r->x1; |
---|
1418 | } |
---|
1419 | |
---|
1420 | rcl->xLeft = ( tmp_x1 * realzoom ) - sHscrollPos; |
---|
1421 | rcl->yBottom = cyClient - ( yplus + ( tmp_y2 * realzoom ) ) + ( sVscrollPos * VScrollStep ); |
---|
1422 | rcl->xRight = ( tmp_x2 * realzoom ) - sHscrollPos; |
---|
1423 | rcl->yTop = cyClient - ( yplus + ( tmp_y1 * realzoom ) ) + ( sVscrollPos * VScrollStep ); |
---|
1424 | |
---|
1425 | LONG pw = w * realzoom; |
---|
1426 | if ( pw < cxClient ) { |
---|
1427 | LONG xPos = ( cxClient - pw ) / 2; |
---|
1428 | rcl->xLeft += xPos; |
---|
1429 | rcl->xRight += xPos; |
---|
1430 | } |
---|
1431 | if ( !continuous ) |
---|
1432 | { |
---|
1433 | LONG ph = h * realzoom; |
---|
1434 | if ( ph < cyClient ) { |
---|
1435 | LONG yPos = ( cyClient - ph ) / 2; |
---|
1436 | rcl->yBottom -= yPos; |
---|
1437 | rcl->yTop -= yPos; |
---|
1438 | } |
---|
1439 | } |
---|
1440 | } |
---|
1441 | |
---|
1442 | // creates region from sequence of rectangles |
---|
1443 | HRGN DocumentViewer::rectsToRegion( long pagenum, HPS hps, LuDocument_LuRectSequence *rects ) |
---|
1444 | { |
---|
1445 | HRGN hrgn = GpiCreateRegion( hps, 0, NULL ); |
---|
1446 | if ( rects != NULL ) |
---|
1447 | { |
---|
1448 | RECTL r = {0}; |
---|
1449 | for ( int i = 0; i < rects->_length; i++ ) |
---|
1450 | { |
---|
1451 | docPosToWinPos( pagenum, &(rects->_buffer[i]), &r ); |
---|
1452 | HRGN tmprgn = GpiCreateRegion( hps, 1, &r ); |
---|
1453 | GpiCombineRegion( hps, hrgn, hrgn, tmprgn, CRGN_OR ); |
---|
1454 | GpiDestroyRegion( hps, tmprgn ); |
---|
1455 | } |
---|
1456 | } |
---|
1457 | return hrgn; |
---|
1458 | } |
---|
1459 | |
---|
1460 | // draws selected area in window, using XOR mix |
---|
1461 | // drawing area may be restricted by r rectangle |
---|
1462 | void DocumentViewer::drawSelection( long pagenum, HPS hps, PRECTL r ) |
---|
1463 | { |
---|
1464 | GpiSetMix( hps, FM_XOR ); |
---|
1465 | GpiSetColor( hps, CLR_YELLOW ); |
---|
1466 | HRGN selectRegion = rectsToRegion( pagenum, hps, selrects[ pagenum ] ); |
---|
1467 | if ( r != NULL ) |
---|
1468 | { |
---|
1469 | HRGN tmprgn = GpiCreateRegion( hps, 1, r ); |
---|
1470 | GpiCombineRegion( hps, selectRegion, selectRegion, tmprgn, CRGN_AND ); |
---|
1471 | GpiDestroyRegion( hps, tmprgn ); |
---|
1472 | } |
---|
1473 | GpiPaintRegion( hps, selectRegion ); |
---|
1474 | GpiDestroyRegion( hps, selectRegion ); |
---|
1475 | } |
---|
1476 | |
---|
1477 | void DocumentViewer::drawFound( long pagenum, HPS hps, PRECTL r ) |
---|
1478 | { |
---|
1479 | GpiSetMix( hps, FM_XOR ); |
---|
1480 | GpiSetColor( hps, CLR_CYAN ); |
---|
1481 | HRGN selectRegion = rectsToRegion( pagenum, hps, foundrects[ pagenum ] ); |
---|
1482 | if ( r != NULL ) |
---|
1483 | { |
---|
1484 | HRGN tmprgn = GpiCreateRegion( hps, 1, r ); |
---|
1485 | GpiCombineRegion( hps, selectRegion, selectRegion, tmprgn, CRGN_AND ); |
---|
1486 | GpiDestroyRegion( hps, tmprgn ); |
---|
1487 | } |
---|
1488 | GpiPaintRegion( hps, selectRegion ); |
---|
1489 | GpiDestroyRegion( hps, selectRegion ); |
---|
1490 | } |
---|
1491 | |
---|
1492 | // scrolls window to specified pos (optionally with text selection) |
---|
1493 | void DocumentViewer::scrollToPos( HWND hwnd, HRGN hrgn, LONG xpos, LONG ypos, |
---|
1494 | bool withSelection ) |
---|
1495 | { |
---|
1496 | SHORT xinc = 0; |
---|
1497 | SHORT yinc = 0; |
---|
1498 | |
---|
1499 | if ( ( xpos < 0 ) && ( sHscrollPos > 0 ) ) { |
---|
1500 | xinc = __max( sHscrollPos * -1, xpos ); |
---|
1501 | } else if ( ( xpos > cxClient ) && ( sHscrollPos < sHscrollMax ) ) { |
---|
1502 | xinc = __min( sHscrollMax - sHscrollPos, xpos - cxClient ); |
---|
1503 | } |
---|
1504 | if ( ( ypos < 0 ) && ( sVscrollPos < sVscrollMax ) ) { |
---|
1505 | yinc = __min( ( sVscrollMax - sVscrollPos ) * VScrollStep, ypos * -1 ); |
---|
1506 | } |
---|
1507 | else if ( ( ypos > cyClient ) && ( sVscrollPos > 0 ) ) { |
---|
1508 | yinc = __max( ( sVscrollPos * -1 ) * VScrollStep, cyClient - ypos ); |
---|
1509 | } |
---|
1510 | |
---|
1511 | if ( xinc != 0 ) { |
---|
1512 | horizScroll( hwnd, MPFROM2SHORT( sHscrollPos + xinc, SB_SLIDERPOSITION ), hrgn ); |
---|
1513 | if ( withSelection ) { |
---|
1514 | selectionStart.x -= xinc; |
---|
1515 | } |
---|
1516 | } |
---|
1517 | |
---|
1518 | if ( yinc != 0 ) |
---|
1519 | { |
---|
1520 | SHORT remainder = yinc % VScrollStep; |
---|
1521 | if ( remainder != 0 ) { |
---|
1522 | SHORT add = VScrollStep - remainder; |
---|
1523 | yinc += ( ( yinc > 0 ) ? add : -add ); |
---|
1524 | } |
---|
1525 | |
---|
1526 | vertScroll( hwnd, MPFROM2SHORT( ( ( sVscrollPos * VScrollStep ) + yinc ) / VScrollStep, |
---|
1527 | SB_SLIDERPOSITION ), hrgn ); |
---|
1528 | if ( withSelection ) { |
---|
1529 | selectionStart.y += yinc; |
---|
1530 | } |
---|
1531 | } |
---|
1532 | } |
---|
1533 | |
---|
1534 | // handles WM_MOUSEMOVE |
---|
1535 | // performs text selection if mouse button pressed |
---|
1536 | // changes mouse ptr to 'hand' if it moves over link area |
---|
1537 | BOOL DocumentViewer::wmMouseMove( HWND hwnd, SHORT xpos, SHORT ypos ) |
---|
1538 | { |
---|
1539 | if ( zoomMode ) |
---|
1540 | { |
---|
1541 | HPOINTER ptr = zoomInPtr; |
---|
1542 | if ( WinGetPhysKeyState( HWND_DESKTOP, 0x1d ) & 0x8000 ) { |
---|
1543 | ptr = zoomOutPtr; |
---|
1544 | } |
---|
1545 | WinSetPointer( HWND_DESKTOP, ptr ); |
---|
1546 | return TRUE; |
---|
1547 | } |
---|
1548 | else |
---|
1549 | { |
---|
1550 | if ( mousePressed && ( doc != NULL ) ) |
---|
1551 | { |
---|
1552 | selectionEnd.x = xpos; |
---|
1553 | selectionEnd.y = ypos; |
---|
1554 | |
---|
1555 | if ( continuous ) |
---|
1556 | { |
---|
1557 | scrollToPos( hwnd, NULLHANDLE, xpos, ypos, true ); |
---|
1558 | |
---|
1559 | RECTL selRect = { |
---|
1560 | selectionStart.x < selectionEnd.x ? selectionStart.x : selectionEnd.x, |
---|
1561 | selectionStart.y < selectionEnd.y ? selectionStart.y : selectionEnd.y, |
---|
1562 | selectionStart.x < selectionEnd.x ? selectionEnd.x : selectionStart.x, |
---|
1563 | selectionStart.y < selectionEnd.y ? selectionEnd.y : selectionStart.y |
---|
1564 | }; |
---|
1565 | |
---|
1566 | DrawAreas *areas = findDrawAreas( &selRect ); |
---|
1567 | |
---|
1568 | HPS hps = WinGetPS( hwnd ); |
---|
1569 | GpiSetMix( hps, FM_XOR ); |
---|
1570 | GpiSetColor( hps, CLR_YELLOW ); |
---|
1571 | |
---|
1572 | for ( int i = 0; i < areas->size(); i++ ) |
---|
1573 | { |
---|
1574 | PageDrawArea *pda = &(*areas)[ i ]; |
---|
1575 | |
---|
1576 | winPosToDocPos( pda, &(selection[pda->pagenum]) ); |
---|
1577 | |
---|
1578 | HRGN clearRegion = rectsToRegion( pda->pagenum, hps, selrects[ pda->pagenum ] ); |
---|
1579 | LuDocument::freeRectangles( ev, selrects[ pda->pagenum ] ); |
---|
1580 | selrects[ pda->pagenum ] = doc->getSelectionRectangles( ev, pda->pagenum, &(selection[pda->pagenum]) ); |
---|
1581 | HRGN selectRegion = rectsToRegion( pda->pagenum, hps, selrects[ pda->pagenum ] ); |
---|
1582 | GpiCombineRegion( hps, selectRegion, selectRegion, clearRegion, CRGN_XOR ); |
---|
1583 | GpiPaintRegion( hps, selectRegion ); |
---|
1584 | GpiDestroyRegion( hps, clearRegion ); |
---|
1585 | GpiDestroyRegion( hps, selectRegion ); |
---|
1586 | } |
---|
1587 | |
---|
1588 | WinReleasePS( hps ); |
---|
1589 | delete areas; |
---|
1590 | } |
---|
1591 | else |
---|
1592 | { |
---|
1593 | winPosToDocPos( &selectionStart, &selectionEnd, &(selection[currentpage]) ); |
---|
1594 | |
---|
1595 | HPS hps = WinGetPS( hwnd ); |
---|
1596 | HRGN scrolledRegion = NULLHANDLE; //GpiCreateRegion( hps, 0, NULL ); |
---|
1597 | |
---|
1598 | scrollToPos( hwnd, scrolledRegion, xpos, ypos, true ); |
---|
1599 | |
---|
1600 | // 127/191/255 |
---|
1601 | //LONG lclr = ( 127 << 16 ) | ( 191 << 8 ) | 255; |
---|
1602 | //LONG lclr = ( 128 << 16 ) | ( 64 << 8 ); |
---|
1603 | //LONG ltabl[ 1 ] = { lclr }; |
---|
1604 | //GpiCreateLogColorTable( hps, 0, LCOLF_CONSECRGB, 100, 1, ltabl ); |
---|
1605 | |
---|
1606 | GpiSetMix( hps, FM_XOR ); |
---|
1607 | GpiSetColor( hps, CLR_YELLOW ); |
---|
1608 | //GpiSetColor( hps, 100 ); |
---|
1609 | |
---|
1610 | HRGN clearRegion = rectsToRegion( currentpage, hps, selrects[ currentpage ] ); |
---|
1611 | LuDocument::freeRectangles( ev, selrects[ currentpage ] ); |
---|
1612 | if ( ( selectionStart.x == selectionEnd.x ) && |
---|
1613 | ( selectionStart.y == selectionEnd.y ) ) { |
---|
1614 | selrects[ currentpage ] = NULL; |
---|
1615 | memset( &(selection[ currentpage ]), 0, sizeof( LuRectangle ) ); |
---|
1616 | } |
---|
1617 | else { |
---|
1618 | selrects[ currentpage ] = doc->getSelectionRectangles( ev, currentpage, &(selection[currentpage]) ); |
---|
1619 | } |
---|
1620 | HRGN selectRegion = rectsToRegion( currentpage, hps, selrects[ currentpage ] ); |
---|
1621 | GpiCombineRegion( hps, selectRegion, selectRegion, clearRegion, CRGN_XOR ); |
---|
1622 | //GpiCombineRegion( hps, selectRegion, selectRegion, scrolledRegion, CRGN_DIFF ); |
---|
1623 | GpiPaintRegion( hps, selectRegion ); |
---|
1624 | GpiDestroyRegion( hps, clearRegion ); |
---|
1625 | GpiDestroyRegion( hps, selectRegion ); |
---|
1626 | //GpiDestroyRegion( hps, scrolledRegion ); |
---|
1627 | |
---|
1628 | WinReleasePS( hps ); |
---|
1629 | } |
---|
1630 | } |
---|
1631 | else if ( links != NULL ) |
---|
1632 | { |
---|
1633 | long pg = currentpage; |
---|
1634 | if ( continuous ) { |
---|
1635 | double tmp; |
---|
1636 | pg = posToPagenum( ypos, &tmp ); |
---|
1637 | } |
---|
1638 | |
---|
1639 | if ( ( pg != -1 ) && ( links[ pg ] != NULL ) ) |
---|
1640 | { |
---|
1641 | for ( int i = 0; i < links[ pg ]->_length; i++ ) |
---|
1642 | { |
---|
1643 | RECTL r = {0}; |
---|
1644 | docPosToWinPos( pg, &(links[ pg ]->_buffer[i].area), &r ); |
---|
1645 | |
---|
1646 | POINTL ptl = { xpos, ypos }; |
---|
1647 | if ( WinPtInRect( hab, &r, &ptl ) ) { |
---|
1648 | WinSetPointer( HWND_DESKTOP, handPtr ); |
---|
1649 | return TRUE; |
---|
1650 | } |
---|
1651 | } |
---|
1652 | } |
---|
1653 | } |
---|
1654 | } |
---|
1655 | return FALSE; |
---|
1656 | } |
---|
1657 | |
---|
1658 | // handles WM_BUTTON1CLICK |
---|
1659 | BOOL DocumentViewer::wmClick( HWND hwnd, SHORT xpos, SHORT ypos ) |
---|
1660 | { |
---|
1661 | if ( zoomMode ) |
---|
1662 | { |
---|
1663 | double z = getRealZoom() / 4; |
---|
1664 | double zval = 0; |
---|
1665 | bool doPlus = false; |
---|
1666 | if ( WinGetPhysKeyState( HWND_DESKTOP, 0x1d ) & 0x8000 ) { |
---|
1667 | zval = getRealZoom() - z; |
---|
1668 | } else { |
---|
1669 | zval = getRealZoom() + z; |
---|
1670 | doPlus = true; |
---|
1671 | } |
---|
1672 | zval = (long)( zval * 20.0 ) / 20.0; // Round to 0.05 (5%) |
---|
1673 | if ( zval == getRealZoom() ) { |
---|
1674 | zval += ( doPlus ? 0.01 : -0.01 ); |
---|
1675 | } |
---|
1676 | if ( zval > 0.1 ) { |
---|
1677 | Lucide::setZoom( zval ); |
---|
1678 | } |
---|
1679 | return TRUE; |
---|
1680 | } |
---|
1681 | else |
---|
1682 | { |
---|
1683 | if ( links == NULL ) { |
---|
1684 | return FALSE; |
---|
1685 | } |
---|
1686 | |
---|
1687 | long pg = currentpage; |
---|
1688 | if ( continuous ) { |
---|
1689 | double tmp; |
---|
1690 | pg = posToPagenum( ypos, &tmp ); |
---|
1691 | } |
---|
1692 | |
---|
1693 | if ( ( pg != -1 ) && ( links[ pg ] != NULL ) ) |
---|
1694 | { |
---|
1695 | for ( int i = 0; i < links[ pg ]->_length; i++ ) |
---|
1696 | { |
---|
1697 | RECTL r = {0}; |
---|
1698 | docPosToWinPos( pg, &(links[ pg ]->_buffer[i].area), &r ); |
---|
1699 | |
---|
1700 | POINTL ptl = { xpos, ypos }; |
---|
1701 | if ( WinPtInRect( hab, &r, &ptl ) ) |
---|
1702 | { |
---|
1703 | if ( links[ pg ]->_buffer[i].link.type == LU_LINK_TYPE_EXTERNAL_URI ) |
---|
1704 | { |
---|
1705 | WinMessageBox( HWND_DESKTOP, hMainFrame, |
---|
1706 | links[ pg ]->_buffer[i].link.uri, "URI", 1, |
---|
1707 | MB_OK | MB_INFORMATION | MB_MOVEABLE ); |
---|
1708 | } |
---|
1709 | else if ( links[ pg ]->_buffer[i].link.type == LU_LINK_TYPE_TITLE ) |
---|
1710 | { |
---|
1711 | char *title = links[ pg ]->_buffer[i].link.title; |
---|
1712 | if ( title == NULL ) { |
---|
1713 | title = "???"; |
---|
1714 | } |
---|
1715 | WinMessageBox( HWND_DESKTOP, hMainFrame, |
---|
1716 | title, "?", 1, MB_OK | MB_INFORMATION | MB_MOVEABLE ); |
---|
1717 | } |
---|
1718 | else if ( links[ pg ]->_buffer[i].link.type == LU_LINK_TYPE_PAGE ) |
---|
1719 | { |
---|
1720 | goToPage( links[ pg ]->_buffer[i].link.page ); |
---|
1721 | } |
---|
1722 | |
---|
1723 | return TRUE; |
---|
1724 | } |
---|
1725 | } |
---|
1726 | } |
---|
1727 | } |
---|
1728 | return FALSE; |
---|
1729 | } |
---|
1730 | |
---|
1731 | |
---|
1732 | BOOL DocumentViewer::wmChar( HWND hwnd, MPARAM mp1, MPARAM mp2 ) |
---|
1733 | { |
---|
1734 | USHORT fsflags = SHORT1FROMMP( mp1 ); |
---|
1735 | USHORT usch = SHORT1FROMMP( mp2 ); |
---|
1736 | USHORT usvk = SHORT2FROMMP( mp2 ); |
---|
1737 | |
---|
1738 | if ( ( fsflags & KC_VIRTUALKEY ) && !( fsflags & KC_KEYUP ) ) |
---|
1739 | { |
---|
1740 | switch ( usvk ) |
---|
1741 | { |
---|
1742 | case VK_UP: |
---|
1743 | WinSendMsg( hwnd, WM_VSCROLL, MPVOID, MPFROM2SHORT( 0, SB_LINEUP ) ); |
---|
1744 | return TRUE; |
---|
1745 | |
---|
1746 | case VK_DOWN: |
---|
1747 | WinSendMsg( hwnd, WM_VSCROLL, MPVOID, MPFROM2SHORT( 0, SB_LINEDOWN ) ); |
---|
1748 | return TRUE; |
---|
1749 | |
---|
1750 | case VK_PAGEUP: |
---|
1751 | if ( fsflags & KC_CTRL ) |
---|
1752 | { |
---|
1753 | if ( fullscreen ) { |
---|
1754 | goToPage( 0 ); |
---|
1755 | } else { |
---|
1756 | vertScroll( hwnd, MPFROM2SHORT( 0, SB_SLIDERPOSITION ), NULLHANDLE ); |
---|
1757 | } |
---|
1758 | } |
---|
1759 | else |
---|
1760 | { |
---|
1761 | bool dojump = ( !continuous && ( sVscrollPos == 0 ) |
---|
1762 | && ( currentpage > 0 ) ); |
---|
1763 | |
---|
1764 | if ( fullscreen || dojump ) { |
---|
1765 | goToPage( currentpage - 1 ); |
---|
1766 | if ( dojump ) { |
---|
1767 | vertScroll( hwnd, MPFROM2SHORT( sVscrollMax, SB_SLIDERPOSITION ), NULLHANDLE ); |
---|
1768 | } |
---|
1769 | } else { |
---|
1770 | WinSendMsg( hwnd, WM_VSCROLL, MPVOID, MPFROM2SHORT( 0, SB_PAGEUP ) ); |
---|
1771 | } |
---|
1772 | } |
---|
1773 | return TRUE; |
---|
1774 | |
---|
1775 | case VK_PAGEDOWN: |
---|
1776 | if ( fsflags & KC_CTRL ) |
---|
1777 | { |
---|
1778 | if ( fullscreen ) { |
---|
1779 | goToPage( totalpages - 1 ); |
---|
1780 | } else { |
---|
1781 | vertScroll( hwnd, MPFROM2SHORT( sVscrollMax, SB_SLIDERPOSITION ), NULLHANDLE ); |
---|
1782 | } |
---|
1783 | } |
---|
1784 | else |
---|
1785 | { |
---|
1786 | bool dojump = ( !continuous && ( sVscrollPos == sVscrollMax ) ); |
---|
1787 | |
---|
1788 | if ( fullscreen || dojump ) { |
---|
1789 | goToPage( currentpage + 1 ); |
---|
1790 | } else { |
---|
1791 | WinSendMsg( hwnd, WM_VSCROLL, MPVOID, MPFROM2SHORT( 0, SB_PAGEDOWN ) ); |
---|
1792 | } |
---|
1793 | } |
---|
1794 | return TRUE; |
---|
1795 | |
---|
1796 | case VK_LEFT: |
---|
1797 | WinSendMsg( hwnd, WM_HSCROLL, MPVOID, MPFROM2SHORT( 0, SB_LINELEFT ) ); |
---|
1798 | return TRUE; |
---|
1799 | |
---|
1800 | case VK_RIGHT: |
---|
1801 | WinSendMsg( hwnd, WM_HSCROLL, MPVOID, MPFROM2SHORT( 0, SB_LINERIGHT ) ); |
---|
1802 | return TRUE; |
---|
1803 | |
---|
1804 | case VK_HOME: |
---|
1805 | horizScroll( hwnd, MPFROM2SHORT( 0, SB_SLIDERPOSITION ), NULLHANDLE ); |
---|
1806 | return TRUE; |
---|
1807 | |
---|
1808 | case VK_END: |
---|
1809 | horizScroll( hwnd, MPFROM2SHORT( sHscrollMax, SB_SLIDERPOSITION ), NULLHANDLE ); |
---|
1810 | return TRUE; |
---|
1811 | } |
---|
1812 | } |
---|
1813 | |
---|
1814 | // Ctrl+L |
---|
1815 | if ( ( fsflags & KC_CTRL ) && !( fsflags & KC_KEYUP ) && ( toupper( usch ) == 'L' ) ) |
---|
1816 | { |
---|
1817 | Lucide::toggleFullscreen(); |
---|
1818 | return TRUE; |
---|
1819 | } |
---|
1820 | |
---|
1821 | // + |
---|
1822 | if ( ( fsflags & KC_CHAR ) && !( fsflags & KC_KEYUP ) && ( usch == '+' ) ) { |
---|
1823 | goToPage( currentpage + 1 ); |
---|
1824 | return TRUE; |
---|
1825 | } |
---|
1826 | // - |
---|
1827 | if ( ( fsflags & KC_CHAR ) && !( fsflags & KC_KEYUP ) && ( usch == '-' ) ) { |
---|
1828 | goToPage( currentpage - 1 ); |
---|
1829 | return TRUE; |
---|
1830 | } |
---|
1831 | |
---|
1832 | // Ctrl |
---|
1833 | if ( ( fsflags & KC_VIRTUALKEY ) && ( usvk == VK_CTRL ) && zoomMode ) { |
---|
1834 | wmMouseMove( hwnd, 0, 0 ); // to switch mouse pointer if in zoomMode |
---|
1835 | } |
---|
1836 | |
---|
1837 | return FALSE; |
---|
1838 | } |
---|
1839 | |
---|
1840 | // handles WM_BUTTON1DOWN |
---|
1841 | void DocumentViewer::wmButton1Down( HWND hwnd, SHORT xpos, SHORT ypos ) |
---|
1842 | { |
---|
1843 | if ( continuous && ( doc != NULL ) ) |
---|
1844 | { |
---|
1845 | // clear selection |
---|
1846 | RECTL rcl = { 0 }; |
---|
1847 | WinQueryWindowRect( hwnd, &rcl ); |
---|
1848 | DrawAreas *areas = findDrawAreas( &rcl ); |
---|
1849 | |
---|
1850 | HPS hps = WinGetPS( hwnd ); |
---|
1851 | GpiSetMix( hps, FM_XOR ); |
---|
1852 | GpiSetColor( hps, CLR_YELLOW ); |
---|
1853 | |
---|
1854 | for ( int i = 0; i < areas->size(); i++ ) |
---|
1855 | { |
---|
1856 | PageDrawArea *pda = &(*areas)[ i ]; |
---|
1857 | |
---|
1858 | HRGN clearRegion = rectsToRegion( pda->pagenum, hps, selrects[ pda->pagenum ] ); |
---|
1859 | GpiPaintRegion( hps, clearRegion ); |
---|
1860 | GpiDestroyRegion( hps, clearRegion ); |
---|
1861 | } |
---|
1862 | WinReleasePS( hps ); |
---|
1863 | delete areas; |
---|
1864 | |
---|
1865 | freeRects( selrects ); |
---|
1866 | |
---|
1867 | memset( selection, 0, sizeof( LuRectangle ) * totalpages ); |
---|
1868 | } |
---|
1869 | |
---|
1870 | WinSetCapture( HWND_DESKTOP, hwnd ); |
---|
1871 | mousePressed = true; |
---|
1872 | selectionStart.x = xpos; |
---|
1873 | selectionStart.y = ypos; |
---|
1874 | } |
---|
1875 | |
---|
1876 | // handles WM_BUTTON1UP |
---|
1877 | void DocumentViewer::wmButton1Up() |
---|
1878 | { |
---|
1879 | WinSetCapture( HWND_DESKTOP, NULLHANDLE ); |
---|
1880 | mousePressed = false; |
---|
1881 | |
---|
1882 | bool haveSelection = false; |
---|
1883 | for ( long i = 0; i < totalpages; i++ ) { |
---|
1884 | if ( selrects[ i ] != NULL ) { |
---|
1885 | haveSelection = true; |
---|
1886 | break; |
---|
1887 | } |
---|
1888 | } |
---|
1889 | |
---|
1890 | Lucide::enableCopy( haveSelection ); |
---|
1891 | } |
---|
1892 | |
---|
1893 | |
---|
1894 | // handles DM_DRAGOVER |
---|
1895 | MRESULT DocumentViewer::wmDragOver( PDRAGINFO dragInfo ) |
---|
1896 | { |
---|
1897 | PDRAGITEM dragItem; |
---|
1898 | USHORT usOp, usIndicator; |
---|
1899 | |
---|
1900 | usOp = 0; |
---|
1901 | usIndicator = DOR_NODROPOP; |
---|
1902 | |
---|
1903 | DrgAccessDraginfo( dragInfo ); |
---|
1904 | |
---|
1905 | if ( dragInfo->usOperation == DO_DEFAULT ) |
---|
1906 | { |
---|
1907 | dragItem = DrgQueryDragitemPtr( dragInfo, 0 ); |
---|
1908 | if ( DrgQueryDragitemCount( dragInfo ) == 1 ) |
---|
1909 | { |
---|
1910 | if ( DrgVerifyRMF( dragItem, "DRM_OS2FILE", NULL ) && |
---|
1911 | ( dragItem->hstrContainerName != NULLHANDLE ) && |
---|
1912 | ( dragItem->hstrSourceName != NULLHANDLE ) ) |
---|
1913 | { |
---|
1914 | char fname[ CCHMAXPATHCOMP ] = ""; |
---|
1915 | DrgQueryStrName( dragItem->hstrSourceName, CCHMAXPATHCOMP, fname ); |
---|
1916 | char *ext = strrchr( fname, '.' ); |
---|
1917 | if ( ext != NULL ) { |
---|
1918 | if ( pluginMan->createDocumentForExt( ext + 1, true ) != NULL ) { |
---|
1919 | usIndicator = DOR_DROP; |
---|
1920 | usOp = DO_UNKNOWN; |
---|
1921 | } |
---|
1922 | } |
---|
1923 | } |
---|
1924 | } |
---|
1925 | } |
---|
1926 | |
---|
1927 | DrgFreeDraginfo( dragInfo ); |
---|
1928 | return MRFROM2SHORT( usIndicator, usOp ); |
---|
1929 | } |
---|
1930 | |
---|
1931 | |
---|
1932 | // handles DM_DROP |
---|
1933 | void DocumentViewer::wmDrop( PDRAGINFO dragInfo ) |
---|
1934 | { |
---|
1935 | PDRAGITEM dragItem; |
---|
1936 | |
---|
1937 | DrgAccessDraginfo( dragInfo ); |
---|
1938 | dragItem = DrgQueryDragitemPtr( dragInfo, 0 ); |
---|
1939 | |
---|
1940 | char fname[ CCHMAXPATHCOMP ] = ""; |
---|
1941 | char fpath[ CCHMAXPATH ] = ""; |
---|
1942 | DrgQueryStrName( dragItem->hstrSourceName, CCHMAXPATHCOMP, fname ); |
---|
1943 | DrgQueryStrName( dragItem->hstrContainerName, CCHMAXPATH, fpath ); |
---|
1944 | DrgFreeDraginfo( dragInfo ); |
---|
1945 | |
---|
1946 | strcat( fpath, fname ); |
---|
1947 | Lucide::loadDocument( fpath ); |
---|
1948 | } |
---|
1949 | |
---|
1950 | |
---|
1951 | // static, window procedure |
---|
1952 | MRESULT EXPENTRY DocumentViewer::docViewProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) |
---|
1953 | { |
---|
1954 | DocumentViewer *_this = (DocumentViewer *)WinQueryWindowULong( hwnd, QWL_USER ); |
---|
1955 | |
---|
1956 | switch ( msg ) |
---|
1957 | { |
---|
1958 | case WM_CREATE: |
---|
1959 | { |
---|
1960 | // Save the mp1 into our user data so that subsequent calls have |
---|
1961 | // access to the parent C++ object |
---|
1962 | WinSetWindowULong( hwnd, QWL_USER, (ULONG)mp1 ); |
---|
1963 | _this = (DocumentViewer *)mp1; |
---|
1964 | return (MRESULT)FALSE; |
---|
1965 | } |
---|
1966 | |
---|
1967 | case DM_DRAGOVER: |
---|
1968 | return _this->wmDragOver( (PDRAGINFO)mp1 ); |
---|
1969 | |
---|
1970 | case DM_DROP: |
---|
1971 | _this->wmDrop( (PDRAGINFO)mp1 ); |
---|
1972 | return (MRESULT)FALSE; |
---|
1973 | |
---|
1974 | case WM_ERASEBACKGROUND: |
---|
1975 | return (MRESULT)TRUE; |
---|
1976 | |
---|
1977 | case WM_SIZE: |
---|
1978 | _this->wmSize( hwnd, mp2 ); |
---|
1979 | return (MRESULT)FALSE; |
---|
1980 | |
---|
1981 | case WM_HSCROLL: |
---|
1982 | _this->horizScroll( hwnd, mp2, NULLHANDLE ); |
---|
1983 | break; |
---|
1984 | |
---|
1985 | case WM_VSCROLL: |
---|
1986 | _this->vertScroll( hwnd, mp2, NULLHANDLE ); |
---|
1987 | break; |
---|
1988 | |
---|
1989 | case WM_PAINT: |
---|
1990 | if ( _this->enableAsynchDraw ) { |
---|
1991 | if ( _this->continuous ) { |
---|
1992 | _this->wmPaintContAsynch( hwnd ); |
---|
1993 | } else { |
---|
1994 | _this->wmPaintAsynch( hwnd ); |
---|
1995 | } |
---|
1996 | } else { |
---|
1997 | if ( _this->continuous ) { |
---|
1998 | _this->wmPaintCont( hwnd ); |
---|
1999 | } else { |
---|
2000 | _this->wmPaint( hwnd ); |
---|
2001 | } |
---|
2002 | } |
---|
2003 | return (MRESULT)FALSE; |
---|
2004 | |
---|
2005 | case WM_BUTTON1DOWN: |
---|
2006 | _this->wmButton1Down( hwnd, SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) ); |
---|
2007 | break; |
---|
2008 | |
---|
2009 | case WM_BUTTON1UP: |
---|
2010 | _this->wmButton1Up(); |
---|
2011 | break; |
---|
2012 | |
---|
2013 | case WM_MOUSEMOVE: |
---|
2014 | if ( _this->wmMouseMove( hwnd, SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) ) ) { |
---|
2015 | return (MRESULT)TRUE; |
---|
2016 | } |
---|
2017 | break; |
---|
2018 | |
---|
2019 | case WM_BUTTON1CLICK: |
---|
2020 | if ( _this->wmClick( hwnd, SHORT1FROMMP( mp1 ), SHORT2FROMMP( mp1 ) ) ) { |
---|
2021 | return (MRESULT)TRUE; |
---|
2022 | } |
---|
2023 | break; |
---|
2024 | |
---|
2025 | case WM_CHAR: |
---|
2026 | if ( _this->wmChar( hwnd, mp1, mp2 ) ) { |
---|
2027 | return (MRESULT)TRUE; |
---|
2028 | } |
---|
2029 | break; |
---|
2030 | } |
---|
2031 | |
---|
2032 | return WinDefWindowProc( hwnd, msg, mp1, mp2 ); |
---|
2033 | } |
---|
2034 | |
---|
2035 | |
---|
2036 | // static, window procedure |
---|
2037 | MRESULT EXPENTRY DocumentViewer::docFrameProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 ) |
---|
2038 | { |
---|
2039 | DocumentViewer *_this = (DocumentViewer *)WinQueryWindowULong( hwnd, QWL_USER ); |
---|
2040 | |
---|
2041 | switch ( msg ) |
---|
2042 | { |
---|
2043 | case WM_SYSCOMMAND: |
---|
2044 | // Send WM_SYSCOMMAND messages to main frame |
---|
2045 | WinSendMsg( _this->hMainFrame, WM_SYSCOMMAND, mp1, mp2 ); |
---|
2046 | return (MRESULT)FALSE; |
---|
2047 | } |
---|
2048 | |
---|
2049 | return _this->oldFrameProc( hwnd, msg, mp1, mp2 ); |
---|
2050 | } |
---|
2051 | |
---|