|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/vibrant/document.c |
source navigation diff markup identifier search freetext search file search |
1 /* document.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: document.c
27 *
28 * Author: Jonathan Kans
29 *
30 * Version Creation Date: 4/12/93
31 *
32 * $Revision: 6.23 $
33 *
34 * File Description: Converts fielded text into final report in a document
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * Date Name Description of modification
39 * ------- ---------- -----------------------------------------------------
40 *
41 * ==========================================================================
42 */
43
44 #include <vibrant.h>
45 #include <document.h>
46 #include <ncbilang.h>
47
48 /*****************************************************************************
49 *
50 * SYMBOL DEFINES
51 *
52 *****************************************************************************/
53
54 #define JUST_LEFT 0
55 #define JUST_CENTER 1
56 #define JUST_RIGHT 2
57
58 #define MAXLISTS 256
59 #define LISTSIZE 256
60 #define MAXFONTS 32
61
62 /*****************************************************************************
63 *
64 * TYPE DEFINES
65 *
66 *****************************************************************************/
67
68 typedef struct colxdata {
69 FonT font;
70 Int2 position;
71 Int2 pixWidth;
72 Int2 pixInset;
73 Int2 charWidth;
74 Int2 charInset;
75 unsigned int just : 2;
76 unsigned int zeroWidth : 1;
77 unsigned int wrap : 1;
78 unsigned int bar : 1;
79 unsigned int underline : 1;
80 unsigned int left : 1;
81 unsigned int last : 1;
82 } ColXData, PNTR ColXPtr;
83
84 typedef struct itemdata {
85 DocPrntProc prtProc;
86 Pointer dataPtr;
87 CharPtr text;
88 CharPtr cached;
89 FonT font;
90 ColXPtr colFmt;
91 VoidPtr extra;
92 Int4 startsAt;
93 Int2 numRows;
94 Int2 numCols;
95 Int2 lineHeight;
96 Int2 leadHeight;
97 Int2 minLines;
98 Int2 minHeight;
99 unsigned int openSpace : 1;
100 unsigned int keepWithNext : 1;
101 unsigned int keepTogether : 1;
102 unsigned int newPage : 1;
103 unsigned int tabStops : 1;
104 unsigned int docOwnsData : 1;
105 unsigned int notCached : 1;
106 unsigned int neverCached : 1;
107 } ItemData, PNTR ItemPtr;
108
109 typedef struct listdata {
110 ItemData items [LISTSIZE];
111 } ListData, PNTR ListDPtr;
112
113 typedef struct masterdata {
114 ListDPtr list [MAXLISTS];
115 } MasterData, PNTR MasterPtr;
116
117 typedef struct docdata {
118 DoC doc;
119 MasterPtr master;
120 DocDrawProc draw;
121 DocCellProc drawcell;
122 DocPanProc pan;
123 DocShadeProc gray;
124 DocShadeProc invert;
125 DocShadeProc color;
126 DocPutProc put;
127 DocGetProc get;
128 DocUpdProc upd;
129 VoidPtr data;
130 DocFreeProc cleanup;
131 ValNodePtr colFmts;
132 Int2 numItems;
133 Int4 numLines;
134 Int4 barmax;
135 Int2 pgUp;
136 Int2 pgDn;
137 Int2 tabCount;
138 Boolean autoAdjust;
139 ParPtr defaultParFmt;
140 ColPtr defaultColFmt;
141 FonT defaultFont;
142 Int2 firstHighlightItem;
143 Int2 lastHighlightItem;
144 Boolean useRowsNotItems;
145 DocNotfyProc notify;
146 } DocData, PNTR DocDataPtr;
147
148 /*****************************************************************************
149 *
150 * justToChar
151 * Converts justification parameter to character code
152 *
153 *****************************************************************************/
154
155 static Char justToChar [4] = {'l', 'c', 'r', 'l'};
156
157 /*****************************************************************************
158 *
159 * fontHeights
160 * Cached list of fonts and font pixel heights
161 *
162 *****************************************************************************/
163
164 static struct fontheights {
165 FonT font;
166 Int2 height;
167 } fontHeights [MAXFONTS];
168
169 /*****************************************************************************
170 *
171 * GetItemPtr (ddatptr, item)
172 * Returns an item pointer given an item number
173 *
174 *****************************************************************************/
175
176 static ItemPtr GetItemPtr (DocDataPtr ddatptr, Int2 item)
177
178 {
179 Int2 index;
180 Int2 list;
181 ItemPtr itemPtr;
182 ListDPtr listPtr;
183 MasterPtr masterPtr;
184
185 itemPtr = NULL;
186 if (ddatptr != NULL && ddatptr->master != NULL && item < ddatptr->numItems) {
187 list = (item / LISTSIZE);
188 if (list < MAXLISTS) {
189 masterPtr = ddatptr->master;
190 listPtr = masterPtr->list [list];
191 if (listPtr != NULL) {
192 index = (item % LISTSIZE);
193 itemPtr = &(listPtr->items [index]);
194 }
195 }
196 }
197 return itemPtr;
198 }
199
200 /*****************************************************************************
201 *
202 * GetItemNum (ddatptr, desired)
203 * Returns the number of the item containing the desired line
204 *
205 *****************************************************************************/
206
207 static Int2 GetItemNum (DocDataPtr ddatptr, Int4 desired)
208
209 {
210 Boolean goOn;
211 ItemPtr itemPtr;
212 Int4 left;
213 Int4 mid;
214 Int4 right;
215
216 mid = 1;
217 if (ddatptr != NULL) {
218 left = 1;
219 right = ddatptr->numItems;
220 goOn = TRUE;
221 while (left <= right && goOn) {
222 mid = (left + right) / 2;
223 itemPtr = GetItemPtr (ddatptr, mid - 1);
224 if (itemPtr != NULL) {
225 if (desired < itemPtr->startsAt + itemPtr->numRows) {
226 right = mid - 1;
227 }
228 if (desired >= itemPtr->startsAt) {
229 left = mid + 1;
230 }
231 } else {
232 goOn = FALSE;
233 mid = 1;
234 }
235 }
236 }
237 return mid - 1;
238 }
239
240 /*****************************************************************************
241 *
242 * GetNextBlock (title, maxwid, byPixels, wordWrap, tabStops, tabCount)
243 * Returns the number of characters in the next block, including
244 * trailing spaces (which are trimmed back later)
245 *
246 *****************************************************************************/
247
248 static Int2 GetNextBlock (CharPtr title, Int2 maxwid, Boolean byPixels,
249 Boolean wordWrap, Boolean tabStops, Int2 tabCount)
250
251 {
252 Char ch;
253 Int2 i;
254 Boolean isjapanese;
255 Int2 j;
256 Int2 wid;
257
258 isjapanese = IsJapanese ();
259 if (isjapanese) {
260 i = 0;
261 j = 0;
262 wid = 0;
263 if (title != NULL && maxwid > 0) {
264 ch = title [i];
265 while (ch != '\0' && ch != '\n' && ch != '\r' &&
266 (ch != '\t' || tabStops) && wid <= maxwid) {
267 if (wordWrap) {
268 if (ch == '\t' && tabStops) {
269 if (byPixels) {
270 wid += CharWidth (' ') * tabCount;
271 } else {
272 wid += tabCount;
273 }
274 } else {
275 if (byPixels) {
276 wid += TextWidth(title + i, Nlm_LetterByte(title + i));
277 } else {
278 wid += Nlm_LetterByte(title + i);
279 }
280 }
281 }
282 i += Nlm_LetterByte(title + i);
283 ch = title [i];
284 }
285 j = i;
286 /* sorry, 1 or 2 byte letters only. but isn't it enough ? */
287 #define BackIsMBLetter(str, i) ((i > 1) && (IsMBLetter(title + i - 2)))
288 #define BackStep(str, i) (BackIsMBLetter(str, i) ? 2 : 1)
289 if (wid > maxwid && wordWrap) {
290 j -= BackStep(title, j);
291 if (byPixels) {
292 while (TextWidth (title, i) > maxwid) {
293 i -= BackStep(title, i);
294 }
295 } else {
296 while (i > maxwid) {
297 i -= BackStep(title, i);
298 }
299 }
300 while (i > 0 && title[i - 1] != ' ' && title [i - 1] != '-' &&
301 !(BackIsMBLetter(title, i))) {
302 /* at least in Japanese, almost all of multibyte letters are
303 good as a word wrap point. */
304 i -= BackStep(title, i);
305 }
306 while (title [i] == ' ') {
307 i++;
308 }
309 }
310 }
311 } else {
312 i = 0;
313 j = 0;
314 wid = 0;
315 if (title != NULL && maxwid > 0) {
316 ch = title [i];
317 while (ch != '\0' && ch != '\n' && ch != '\r' &&
318 (ch != '\t' || tabStops) && wid <= maxwid) {
319 if (wordWrap) {
320 if (ch == '\t' && tabStops) {
321 if (byPixels) {
322 wid += CharWidth (' ') * tabCount;
323 } else {
324 wid += tabCount;
325 }
326 } else {
327 if (byPixels) {
328 wid += CharWidth (ch);
329 } else {
330 wid++;
331 }
332 }
333 }
334 i++;
335 ch = title [i];
336 }
337 j = i;
338 if (wid > maxwid && wordWrap) {
339 j--;
340 if (byPixels) {
341 while (TextWidth (title, i) > maxwid) {
342 i--;
343 }
344 } else {
345 while (i > maxwid) {
346 i--;
347 }
348 }
349 while (i > 0 && title [i - 1] != ' ' && title [i - 1] != '-') {
350 i--;
351 }
352 while (title [i] == ' ') {
353 i++;
354 }
355 }
356 }
357 }
358 if (i > 0 && i < j) {
359 return i;
360 } else if (j > 0) {
361 return j;
362 } else {
363 return 0;
364 }
365 }
366
367 /*****************************************************************************
368 *
369 * CELL STRUCTURE DEFINITIONS
370 *
371 *****************************************************************************/
372
373 #define CELLCHUNK 128
374
375 typedef struct celldata {
376 Uint4 start;
377 Int2 count;
378 } CellData, PNTR CellPtr;
379
380 typedef struct parsedata {
381 Int4 numCells;
382 CellPtr cellPtr;
383 } ParseData, PNTR ParsePtr;
384
385 /*****************************************************************************
386 *
387 * RecordCell (itemPtr, parsePtr, start, len, row, col)
388 * Records the character position and length for a given cell
389 *
390 *****************************************************************************/
391
392 static void RecordCell (ItemPtr itemPtr, ParsePtr parsePtr,
393 Uint4 start, Int2 len, Int2 row, Int2 col)
394
395 {
396 Int4 cell;
397 CellPtr cellPtr;
398 Int4 newCells;
399 Int4 numCells;
400
401 if (itemPtr != NULL && parsePtr != NULL && col < itemPtr->numCols) {
402 numCells = parsePtr->numCells;
403 cellPtr = parsePtr->cellPtr;
404 cell = (Int4) ((Int4) row * (Int4) (itemPtr->numCols) + (Int4) col);
405 if (cell >= (Int4) numCells) {
406 newCells = (cell / CELLCHUNK + 1) * CELLCHUNK;
407 if (cellPtr != NULL) {
408 cellPtr = (CellPtr) MemMore (cellPtr, sizeof (CellData) * newCells);
409 if (cellPtr != NULL) {
410 while (numCells < newCells) {
411 cellPtr [numCells].start = 0;
412 cellPtr [numCells].count = 0;
413 numCells++;
414 }
415 }
416 } else {
417 cellPtr = (CellPtr) MemNew (sizeof (CellData) * newCells);
418 }
419 parsePtr->cellPtr = cellPtr;
420 parsePtr->numCells = newCells;
421 }
422 if (cellPtr != NULL) {
423 cellPtr [cell].start = start;
424 cellPtr [cell].count = len;
425 }
426 }
427 }
428
429 /*****************************************************************************
430 *
431 * ParseText (itemPtr, parsePtr, text, byPixels, tabCount)
432 * Parses text that contains \t, \r and \n characters into a list of
433 * cells organized by row and column
434 *
435 *****************************************************************************/
436
437 static void ParseText (ItemPtr itemPtr, ParsePtr parsePtr,
438 CharPtr text, Boolean byPixels, Int2 tabCount)
439
440 {
441 Int2 blklen;
442 Char ch;
443 Int2 col;
444 ColXPtr colFmt;
445 FonT curFont;
446 FonT fnt;
447 Int2 inset;
448 Int2 insetLeft;
449 Int2 insetRight;
450 Char just;
451 Int2 len;
452 Int2 maxwid;
453 Int2 numCols;
454 Int2 numRows;
455 Int2 returnRow;
456 Int2 row;
457 Uint4 start;
458 Int2 tabRow;
459 Boolean tabStops;
460 Int2 width;
461 Boolean wrap;
462
463 if (itemPtr != NULL && parsePtr != NULL && text != NULL && *text != '\0') {
464 curFont = NULL;
465 colFmt = itemPtr->colFmt;
466 if (colFmt != NULL) {
467 fnt = itemPtr->font;
468 if (byPixels) {
469 if (fnt != NULL) {
470 SelectFont (fnt);
471 curFont = fnt;
472 } else {
473 SelectFont (systemFont);
474 curFont = systemFont;
475 }
476 }
477 start = 0;
478 row = 0;
479 tabRow = 0;
480 returnRow = 1;
481 col = 0;
482 tabStops = itemPtr->tabStops;
483 numRows = 0;
484 numCols = itemPtr->numCols;
485 while (text [start] != '\0') {
486 len = 0;
487 wrap = FALSE;
488 ch = text [start];
489 if (ch != '\0' && ch != '\n' && ch != '\r' && (ch != '\t' || tabStops)) {
490 maxwid = INT2_MAX;
491 if (col < numCols) {
492 if (byPixels) {
493 width = colFmt [col].pixWidth;
494 inset = colFmt [col].pixInset;
495 } else {
496 width = colFmt [col].charWidth;
497 inset = colFmt [col].charInset;
498 }
499 just = justToChar [colFmt [col].just];
500 wrap = colFmt [col].wrap;
501 fnt = colFmt [col].font;
502 } else {
503 width = 0;
504 inset = 0;
505 just = 'l';
506 wrap = FALSE;
507 fnt = NULL;
508 }
509 if (just == 'c') {
510 insetLeft = inset;
511 insetRight = inset;
512 } else if (just == 'l') {
513 insetLeft = inset;
514 insetRight = 0;
515 } else if (just == 'r') {
516 insetLeft = 0;
517 insetRight = inset;
518 } else {
519 insetLeft = 0;
520 insetRight = 0;
521 }
522 if (byPixels) {
523 if (col < numCols && wrap && width > 0 &&
524 width >= 2 + insetLeft + insetRight) {
525 maxwid = width - 2 - insetLeft - insetRight;
526 }
527 } else {
528 if (col < numCols && wrap && width > 0 &&
529 width >= insetLeft + insetRight) {
530 maxwid = width - insetLeft - insetRight;
531 }
532 }
533 if (byPixels) {
534 if (fnt != NULL) {
535 if (fnt != curFont) {
536 SelectFont (fnt);
537 curFont = fnt;
538 }
539 } else {
540 fnt = itemPtr->font;
541 if (fnt != NULL) {
542 if (fnt != curFont) {
543 SelectFont (fnt);
544 curFont = fnt;
545 }
546 }
547 }
548 }
549 blklen = GetNextBlock (text + start, maxwid, byPixels,
550 wrap, tabStops, tabCount);
551 len = blklen;
552 if (len > 0) {
553 if (text [start + len] != '\0') {
554 while (len > 0 && text [start + len - 1] == ' ') {
555 len--;
556 }
557 if (len == 0) {
558 len = blklen;
559 }
560 }
561 RecordCell (itemPtr, parsePtr, start, len, row, col);
562 if (len > 0 && col < numCols && colFmt [col].zeroWidth) {
563 if (byPixels) {
564 colFmt [col].pixWidth = TextWidth (text + start, len) +
565 CharWidth (' ') + 2;
566 } else {
567 colFmt [col].charWidth = len + 1;
568 }
569 }
570 start += blklen;
571 } else {
572 if (byPixels) {
573 while (TextWidth (text + start, len) <= maxwid) {
574 len++;
575 }
576 } else {
577 while (len <= maxwid) {
578 len++;
579 }
580 }
581 len--;
582 if (len > 0) {
583 RecordCell (itemPtr, parsePtr, start, len, row, col);
584 }
585 ch = text [start];
586 while (ch != '\0' && ch != '\n' && ch != '\r' && ch != '\t') {
587 start++;
588 ch = text [start];
589 }
590 }
591 }
592 ch = text [start];
593 if (ch == '\n') {
594 start++;
595 row = returnRow;
596 tabRow = row;
597 returnRow++;
598 col = 0;
599 } else if (ch == '\r') {
600 start++;
601 row++;
602 returnRow = MAX (returnRow, row + 1);
603 } else if (ch == '\t') {
604 start++;
605 row = tabRow;
606 col++;
607 if (text [start] == '\0') {
608 row = returnRow;
609 }
610 } else if (ch != '\0' && wrap) {
611 if (len == 0) {
612 start++;
613 }
614 row++;
615 returnRow = MAX (returnRow, row + 1);
616 } else if (ch != '\0') {
617 start++;
618 } else if (text [start - 1] != '\n' && text [start - 1] != '\r') {
619 row = returnRow;
620 }
621 numRows = MAX (numRows, row);
622 }
623 itemPtr->numRows = MAX (numRows, itemPtr->minLines);
624 }
625 SelectFont (systemFont);
626 } else if (itemPtr != NULL) {
627 itemPtr->numRows = 0;
628 }
629 }
630
631 /*****************************************************************************
632 *
633 * RearrangeText (itemPtr, parsePtr, text)
634 * Reconstructs text in row and column order so that the list of cells
635 * does not need to persist
636 *
637 *****************************************************************************/
638
639 static void RearrangeText (ItemPtr itemPtr, ParsePtr parsePtr, CharPtr text)
640
641 {
642 Int4 cell;
643 CellPtr cellPtr;
644 Int2 col;
645 ColXPtr colFmt;
646 CharPtr dst;
647 Int4 len;
648 Int2 minLines;
649 Int4 numCells;
650 Int2 numCols;
651 Int2 numRows;
652 Int2 row;
653 CharPtr src;
654 CharPtr str;
655
656 if (itemPtr != NULL && parsePtr != NULL && text != NULL && *text != '\0') {
657 colFmt = itemPtr->colFmt;
658 if (colFmt != NULL) {
659 numRows = itemPtr->numRows;
660 numCols = itemPtr->numCols;
661 minLines = itemPtr->minLines;
662 if (parsePtr->numCells > 0 && parsePtr->cellPtr != NULL) {
663 cellPtr = parsePtr->cellPtr;
664 numCells = parsePtr->numCells;
665 len = (Int4) (numRows * numCols);
666 for (row = 0; row < numRows; row++) {
667 for (col = 0; col < numCols; col++) {
668 cell = (Int4) ((Int4) row * (Int4) numCols + (Int4) col);
669 if (cell < (Int4) numCells) {
670 len += (Int4) (cellPtr [cell].count);
671 }
672 }
673 }
674 len += (Int4) minLines + (Int4) 4;
675 str = NULL;
676 if ((size_t)len < SIZE_MAX) {
677 str = (CharPtr) MemNew ((size_t) (Uint4) len);
678 if (str != NULL) {
679 dst = str;
680 for (row = 0; row < numRows; row++) {
681 for (col = 0; col < numCols; col++) {
682 cell = (Int4) ((Int4) row * (Int4) numCols + (Int4) col);
683 if (cell < numCells) {
684 if (col > 0) {
685 *dst = '\t';
686 dst++;
687 }
688 src = text + cellPtr [cell].start;
689 len = (Int4) (cellPtr [cell].count);
690 while (len > 0) {
691 *dst = *src;
692 dst++;
693 src++;
694 len--;
695 }
696 }
697 }
698 *dst = '\n';
699 dst++;
700 }
701 while (row < minLines) {
702 *dst = '\n';
703 dst++;
704 row++;
705 }
706 *dst = '\0';
707 }
708 }
709 itemPtr->text = str;
710 }
711 }
712 }
713 }
714
715 /*****************************************************************************
716 *
717 * FormatText (ddatptr, item, itemPtr, byPixels, tabCount)
718 * Calls the print function for the item, then parses and rearranges
719 * the text so that it can be displayed, saved, or printed
720 *
721 *****************************************************************************/
722
723 static void FormatText (DocDataPtr ddatptr, Int2 item, ItemPtr itemPtr,
724 Boolean byPixels, Int2 tabCount)
725
726 {
727 Boolean needToParse;
728 ParseData parseData;
729 CharPtr text;
730
731 if (itemPtr != NULL && itemPtr->text == NULL && itemPtr->prtProc != NULL) {
732 needToParse = TRUE;
733 text = NULL;
734 if (ddatptr != NULL && ddatptr->get != NULL) {
735 text = ddatptr->get (ddatptr->doc, item);
736 if (text != NULL) {
737 needToParse = FALSE;
738 } else {
739 text = itemPtr->prtProc (ddatptr->doc, item, itemPtr->dataPtr);
740 }
741 } else if (ddatptr != NULL) {
742 text = itemPtr->prtProc (ddatptr->doc, item, itemPtr->dataPtr);
743 }
744 if (needToParse && text != NULL && *text != '\0') {
745 parseData.numCells = 0;
746 parseData.cellPtr = NULL;
747 ParseText (itemPtr, &parseData, text, byPixels, tabCount);
748 RearrangeText (itemPtr, &parseData, text);
749 itemPtr->notCached = FALSE;
750 itemPtr->neverCached = FALSE;
751 MemFree (text);
752 MemFree (parseData.cellPtr);
753 } else {
754 itemPtr->text = text;
755 }
756 text = itemPtr->text;
757 if (text == NULL || *text == '\0') {
758 MemFree (itemPtr->text);
759 itemPtr->text = StringSave (" \n");
760 itemPtr->numRows = 1;
761 itemPtr->notCached = FALSE;
762 itemPtr->neverCached = FALSE;
763 needToParse = TRUE;
764 }
765 if (needToParse && ddatptr != NULL && ddatptr->put != NULL) {
766 ddatptr->put (ddatptr->doc, item, itemPtr->text);
767 }
768 }
769 }
770
771 /*****************************************************************************
772 *
773 * GetStartsAt (ddatptr, item)
774 * Returns the first line of the item
775 *
776 *****************************************************************************/
777
778 static Int4 GetStartsAt (DocDataPtr ddatptr, Int2 item)
779
780 {
781 Int4 startsAt;
782 ItemPtr itemPtr;
783
784 startsAt = 0;
785 if (ddatptr != NULL) {
786 itemPtr = GetItemPtr (ddatptr, item);
787 if (itemPtr != NULL) {
788 startsAt = itemPtr->startsAt;
789 }
790 }
791 return startsAt;
792 }
793
794 /*****************************************************************************
795 *
796 * GetLineHeight (ddatptr, item)
797 * Returns the pixel height of the item
798 *
799 *****************************************************************************/
800
801 static Int2 GetLineHeight (DocDataPtr ddatptr, Int2 item)
802
803 {
804 ItemPtr itemPtr;
805 Int2 lineHeight;
806
807 lineHeight = 0;
808 if (ddatptr != NULL) {
809 itemPtr = GetItemPtr (ddatptr, item);
810 if (itemPtr != NULL) {
811 lineHeight = itemPtr->lineHeight;
812 }
813 }
814 return lineHeight;
815 }
816
817 /*****************************************************************************
818 *
819 * SetTablePixFormat (colFmt, left, numCols)
820 * Uses pixel widths to calculate the positions of columns for drawing
821 *
822 *****************************************************************************/
823
824 static void SetTablePixFormat (ColXPtr colFmt, Int2 left, Int2 numCols)
825
826 {
827 Int2 i;
828
829 if (colFmt != NULL) {
830 colFmt [0].position = left;
831 for (i = 1; i < numCols; i++) {
832 if (colFmt [i].left) {
833 colFmt [i].position = left;
834 } else {
835 colFmt [i].position = colFmt [i - 1].position + colFmt [i - 1].pixWidth;
836 }
837 }
838 }
839 }
840
841 /*****************************************************************************
842 *
843 * SetTableCharFormat (colFmt, numCols)
844 * Uses character counts to calculate the positions of columns for saving
845 *
846 *****************************************************************************/
847
848 static void SetTableCharFormat (ColXPtr colFmt, Int2 numCols)
849
850 {
851 Int2 i;
852
853 if (colFmt != NULL) {
854 colFmt [0].position = 0;
855 for (i = 1; i < numCols; i++) {
856 if (colFmt [i].left) {
857 colFmt [i].position = 0;
858 } else {
859 colFmt [i].position = colFmt [i - 1].position + colFmt [i - 1].charWidth;
860 }
861 }
862 }
863 }
864
865 /*****************************************************************************
866 *
867 * UpdateLineStarts (ddatptr, frst)
868 * Recalculates the first lines as a running sum of the number of rows
869 *
870 *****************************************************************************/
871
872 static Int4 UpdateLineStarts (DocDataPtr ddatptr, Int2 frst)
873
874 {
875 Int2 i;
876 ItemPtr itemPtr;
877 Int4 totalNumLines;
878
879 totalNumLines = 0;
880 if (ddatptr != NULL) {
881 itemPtr = GetItemPtr (ddatptr, frst);
882 if (itemPtr != NULL) {
883 totalNumLines = itemPtr->startsAt;
884 }
885 for (i = frst; i < ddatptr->numItems; i++) {
886 itemPtr = GetItemPtr (ddatptr, i);
887 if (itemPtr != NULL) {
888 itemPtr->startsAt = totalNumLines;
889 totalNumLines += itemPtr->numRows;
890 }
891 }
892 }
893 return totalNumLines;
894 }
895
896 /*****************************************************************************
897 *
898 * CollectRange (item, lowest, highest)
899 * Records the range of items that were manipulated for the purpose of
900 * updating line starts or uncaching formatted text on items that are
901 * not currently visible
902 *
903 *****************************************************************************/
904
905 static void CollectRange (Int2 item, Int2Ptr lowest, Int2Ptr highest)
906
907 {
908 if (lowest != NULL) {
909 *lowest = MIN (*lowest, item);
910 }
911 if (highest != NULL) {
912 *highest = MAX (*highest, item);
913 }
914 }
915
916 /*****************************************************************************
917 *
918 * CacheAndFormat (ddatptr, item, itemPtr, r, tabCount)
919 * Formats text (for drawing) if the item text is not currently cached
920 *
921 *****************************************************************************/
922
923 static void CacheAndFormat (DocDataPtr ddatptr, Int2 item, ItemPtr itemPtr,
924 RectPtr r, Int2 tabCount)
925
926 {
927 if (itemPtr != NULL && r != NULL && itemPtr->notCached) {
928 SetTablePixFormat (itemPtr->colFmt, r->left, itemPtr->numCols);
929 FormatText (ddatptr, item, itemPtr, TRUE, tabCount);
930 }
931 }
932
933 /*****************************************************************************
934 *
935 * CacheIfNever (ddatptr, item, itemPtr, r, tabCount)
936 * Formats text (for obtaining the correct number of rows) if the item
937 * text has never been cached
938 *
939 *****************************************************************************/
940
941 static void CacheIfNever (DocDataPtr ddatptr, Int2 item, ItemPtr itemPtr,
942 RectPtr r, Int2 tabCount)
943
944 {
945 if (itemPtr != NULL && r != NULL && itemPtr->neverCached) {
946 SetTablePixFormat (itemPtr->colFmt, r->left, itemPtr->numCols);
947 FormatText (ddatptr, item, itemPtr, TRUE, tabCount);
948 }
949 }
950
951 /*****************************************************************************
952 *
953 * FreeCachedItem (ddatptr, item, lowest, highest)
954 * Frees the formatted text string for an item that is not currently
955 * visible
956 *
957 *****************************************************************************/
958
959 static void FreeCachedItem (DocDataPtr ddatptr, Int2 item,
960 Int2Ptr lowest, Int2Ptr highest)
961
962 {
963 ItemPtr itemPtr;
964
965 if (ddatptr != NULL) {
966 itemPtr = GetItemPtr (ddatptr, item);
967 if (itemPtr != NULL) {
968 itemPtr->text = (CharPtr) MemFree (itemPtr->text);
969 itemPtr->notCached = TRUE;
970 }
971 }
972 }
973
974 /*****************************************************************************
975 *
976 * VisLinesAbove (ddatptr, r, item, line, lowest, highest)
977 * Returns the number of lines visible on the screen if the given line
978 * in the given item is the last line visible
979 *
980 *****************************************************************************/
981
982 static Int2 VisLinesAbove (DocDataPtr ddatptr, RectPtr r, Int2 item,
983 Int2 line, Int2Ptr lowest, Int2Ptr highest)
984
985 {
986 ItemPtr itemPtr;
987 Int2 pixels;
988 Int2 vis;
989
990 vis = 0;
991 if (ddatptr != NULL && r != NULL && item < ddatptr->numItems) {
992 pixels = r->bottom - r->top;
993 while (pixels > 0 && item >= 0) {
994 itemPtr = GetItemPtr (ddatptr, item);
995 if (itemPtr != NULL) {
996 CollectRange (item, lowest, highest);
997 CacheIfNever (ddatptr, item + 1, itemPtr, r, ddatptr->tabCount);
998 if (line < 0) {
999 line = itemPtr->numRows - 1;
1000 }
1001 while (pixels > 0 && line >= 0 && line < itemPtr->numRows) {
1002 pixels -= itemPtr->lineHeight;
1003 if (pixels >= 0) {
1004 vis++;
1005 }
1006 line--;
1007 }
1008 pixels -= itemPtr->leadHeight;
1009 }
1010 item--;
1011 }
1012 }
1013 return vis;
1014 }
1015
1016 /*****************************************************************************
1017 *
1018 * VisLinesBelow (ddatptr, r, item, line, lowest, highest)
1019 * Returns the number of lines visible on the screen if the given line
1020 * in the given item is the first line visible
1021 *
1022 *****************************************************************************/
1023
1024 static Int2 VisLinesBelow (DocDataPtr ddatptr, RectPtr r, Int2 item,
1025 Int2 line, Int2Ptr lowest, Int2Ptr highest)
1026
1027 {
1028 ItemPtr itemPtr;
1029 Int2 pixels;
1030 Int2 vis;
1031
1032 vis = 0;
1033 if (ddatptr != NULL && r != NULL && item < ddatptr->numItems && item >= 0) {
1034 pixels = r->bottom - r->top;
1035 while (pixels > 0 && item < ddatptr->numItems) {
1036 itemPtr = GetItemPtr (ddatptr, item);
1037 if (itemPtr != NULL) {
1038 CollectRange (item, lowest, highest);
1039 CacheIfNever (ddatptr, item + 1, itemPtr, r, ddatptr->tabCount);
1040 if (line < 0) {
1041 line = 0;
1042 pixels -= itemPtr->leadHeight;
1043 }
1044 while (pixels > 0 && line >= 0 && line < itemPtr->numRows) {
1045 pixels -= itemPtr->lineHeight;
1046 if (pixels >= 0) {
1047 vis++;
1048 }
1049 line++;
1050 }
1051 line = -1;
1052 }
1053 item++;
1054 }
1055 }
1056 return vis;
1057 }
1058
1059 /*****************************************************************************
1060 *
1061 * PixelsBetween (ddatptr, r, firstLine, lastLine, lowest, highest)
1062 * Returns the number of pixels between two lines
1063 *
1064 *****************************************************************************/
1065
1066 static Int2 PixelsBetween (DocDataPtr ddatptr, RectPtr r, Int4 firstLine,
1067 Int4 lastLine, Int2Ptr lowest, Int2Ptr highest)
1068
1069 {
1070 Int2 count;
1071 Int2 item;
1072 ItemPtr itemPtr;
1073 Int4 line;
1074 Int4 numLines;
1075 Int2 onItem;
1076 Int2 pixels;
1077
1078 pixels = 0;
1079 if (ddatptr != NULL && r != NULL) {
1080 count = ABS (lastLine - firstLine);
1081 item = GetItemNum (ddatptr, MIN (firstLine, lastLine));
1082 itemPtr = GetItemPtr (ddatptr, item);
1083 onItem = item;
1084 if (itemPtr != NULL && item >= 0) {
1085 CollectRange (item, lowest, highest);
1086 CacheIfNever (ddatptr, item + 1, itemPtr, r, ddatptr->tabCount);
1087 line = MIN (firstLine, lastLine) - itemPtr->startsAt;
1088 while (count > 0 && item < ddatptr->numItems) {
1089 if (item != onItem) {
1090 itemPtr = GetItemPtr (ddatptr, item);
1091 onItem = item;
1092 }
1093 numLines = 0;
1094 if (itemPtr != NULL) {
1095 CollectRange (item, lowest, highest);
1096 CacheIfNever (ddatptr, item + 1, itemPtr, r, ddatptr->tabCount);
1097 numLines = itemPtr->numRows;
1098 while (count > 0 && line >= 0 && line < numLines) {
1099 pixels += itemPtr->lineHeight;
1100 line++;
1101 count--;
1102 }
1103 }
1104 item++;
1105 if (line >= numLines) {
1106 itemPtr = GetItemPtr (ddatptr, item);
1107 onItem = item;
1108 if (itemPtr != NULL) {
1109 CollectRange (item, lowest, highest);
1110 CacheIfNever (ddatptr, item + 1, itemPtr, r, ddatptr->tabCount);
1111 pixels += itemPtr->leadHeight;
1112 }
1113 }
1114 line = 0;
1115 }
1116 if (lastLine < firstLine) {
1117 pixels = -pixels;
1118 }
1119 }
1120 }
1121 return pixels;
1122 }
1123
1124 /*****************************************************************************
1125 *
1126 * DrawTableItem (d, ddatptr, itemPtr, r, item, frst, grayProc,
1127 invertProc, colorProc, force, tabCount)
1128 * Draws a given item on the screen, suppressing partial lines
1129 *
1130 *****************************************************************************/
1131
1132 static Boolean is_old_win = FALSE;
1133 #ifdef OS_MSWIN
1134 static Boolean old_win_set = FALSE;
1135 #endif
1136
1137 static Int2 DrawTableItem (DoC d, DocDataPtr ddatptr, ItemPtr itemPtr, RectPtr r,
1138 Int2 item, Int2 frst, DocShadeProc grayProc,
1139 DocShadeProc invertProc, DocShadeProc colorProc,
1140 Boolean force, Int2 tabCount)
1141
1142 {
1143 Int2 barBottom;
1144 Int2 barTop;
1145 Char ch;
1146 Int2 col;
1147 Boolean color;
1148 ColXPtr colFmt;
1149 FonT curFont;
1150 Uint4 currentColor;
1151 Boolean drawBars;
1152 RecT drw;
1153 FonT fnt;
1154 Boolean gray;
1155 Int2 insetLeft;
1156 Int2 insetRight;
1157 Boolean invert;
1158 Char just;
1159 Int2 lineHeight;
1160 Int2 num;
1161 CharPtr ptr;
1162 RecT rct;
1163 Int2 row;
1164 Int2 rsult;
1165 CharPtr text;
1166 CharPtr tmp;
1167
1168 #ifdef OS_MSWIN
1169 if (! old_win_set) {
1170 text = GetOpSysString ();
1171 if (StringICmp (text, "MS WINDOWS 95/98/Me") == 0 ||
1172 StringICmp (text, "MS WINDOWS 3.1") == 0) {
1173 is_old_win = TRUE;
1174 }
1175 text = MemFree (text);
1176 old_win_set = TRUE;
1177 }
1178 #endif
1179
1180 rsult = 0;
1181 if (d != NULL && ddatptr != NULL && itemPtr != NULL && r != NULL) {
1182 text = itemPtr->text;
1183 colFmt = itemPtr->colFmt;
1184 if (text != NULL && *text != '\0' && colFmt != NULL) {
1185 fnt = itemPtr->font;
1186 if (fnt != NULL) {
1187 curFont = fnt;
1188 } else {
1189 curFont = systemFont;
1190 }
1191 SelectFont (curFont);
1192 lineHeight = itemPtr->lineHeight;
1193 rct.top = r->top;
1194 rct.bottom = rct.top;
1195 row = 0;
1196 col = 0;
1197 ptr = text;
1198 ch = *ptr;
1199 currentColor = 0;
1200 if (colorProc != NULL && (! force)) {
1201 currentColor = GetColor ();
1202 }
1203 drawBars = FALSE;
1204 barTop = INT2_MAX;
1205 barBottom = INT2_MIN;
1206 while (ch != '\0') {
1207 if (ch == '\n') {
1208 rct.top = r->top + (row - frst) * lineHeight;
1209 rct.bottom = rct.top + lineHeight;
1210 InvertMode ();
1211 for (col = 0; col < itemPtr->numCols; col++) {
1212 rct.left = colFmt [col].position;
1213 rct.right = rct.left + colFmt [col].pixWidth;
1214 if (colFmt [col].bar) {
1215 drawBars = TRUE;
1216 barTop = MIN (barTop, rct.top);
1217 barBottom = MAX (barBottom, rct.bottom);
1218 }
1219 if (colFmt [col].underline) {
1220 MoveTo (rct.left, rct.bottom - 1);
1221 LineTo (rct.right, rct.bottom - 1);
1222 }
1223 }
1224 CopyMode ();
1225 col = 0;
1226 row++;
1227 ptr++;
1228 } else if (ch == '\t' && (! (itemPtr->tabStops))) {
1229 col++;
1230 ptr++;
1231 ch = *ptr;
1232 if (ch == '\t' && (! (itemPtr->tabStops)) &&
1233 row >= frst && col < itemPtr->numCols) {
1234 rct.top = r->top + (row - frst) * lineHeight;
1235 rct.bottom = rct.top + lineHeight;
1236 rct.left = colFmt [col].position;
1237 rct.right = rct.left + colFmt [col].pixWidth;
1238 LoadRect (&drw, MAX (rct.left, r->left), rct.top,
1239 MIN (rct.right, r->right), rct.bottom);
1240 if (RectInRect (&drw, r) &&
1241 (force || updateRgn == NULL || RectInRgn (&rct, updateRgn))) {
1242 invert = FALSE;
1243 if (invertProc != NULL && (! force)) {
1244 invert = invertProc (d, item + 1, row + 1, col + 1);
1245 } else if (ddatptr->useRowsNotItems) {
1246 invert = (Boolean) (ddatptr->firstHighlightItem <= row + 1 &&
1247 ddatptr->lastHighlightItem >= row + 1);
1248 } else {
1249 invert = (Boolean) (ddatptr->firstHighlightItem <= item + 1 &&
1250 ddatptr->lastHighlightItem >= item + 1);
1251 }
1252 if (invert) {
1253 InvertColors ();
1254 EraseRect (&rct);
1255 InvertColors ();
1256 }
1257 }
1258 }
1259 } else {
1260 num = 0;
1261 while (ch != '\0' && (ch != '\t' || itemPtr->tabStops) && ch != '\n') {
1262 num++;
1263 ch = ptr [num];
1264 }
1265 if (row >= frst && col < itemPtr->numCols) {
1266 rct.top = r->top + (row - frst) * lineHeight;
1267 rct.bottom = rct.top + lineHeight;
1268 rct.left = colFmt [col].position;
1269 rct.right = rct.left + colFmt [col].pixWidth;
1270 LoadRect (&drw, MAX (rct.left, r->left), rct.top,
1271 MIN (rct.right, r->right), rct.bottom);
1272 if (RectInRect (&drw, r) &&
1273 (force || updateRgn == NULL || RectInRgn (&rct, updateRgn))) {
1274 just = justToChar [colFmt [col].just];
1275 if (just == 'c') {
1276 insetLeft = colFmt [col].pixInset;
1277 insetRight = colFmt [col].pixInset;
1278 } else if (just == 'l') {
1279 insetLeft = colFmt [col].pixInset;
1280 insetRight = 0;
1281 } else if (just == 'r') {
1282 insetLeft = 0;
1283 insetRight = colFmt [col].pixInset;
1284 } else {
1285 insetLeft = 0;
1286 insetRight = 0;
1287 }
1288 fnt = colFmt [col].font;
1289 if (fnt != NULL) {
1290 if (fnt != curFont) {
1291 curFont = fnt;
1292 SelectFont (curFont);
1293 }
1294 } else {
1295 fnt = itemPtr->font;
1296 if (fnt != NULL) {
1297 if (fnt != curFont) {
1298 curFont = fnt;
1299 SelectFont (curFont);
1300 }
1301 }
1302 }
1303 color = FALSE;
1304 if (colorProc != NULL && (! force)) {
1305 color = colorProc (d, item + 1, row + 1, col + 1);
1306 if (! color) {
1307 SetColor (currentColor);
1308 }
1309 }
1310 invert = FALSE;
1311 if (invertProc != NULL && (! force)) {
1312 invert = invertProc (d, item + 1, row + 1, col + 1);
1313 } else if (ddatptr->useRowsNotItems) {
1314 invert = (Boolean) (ddatptr->firstHighlightItem <= row + 1 &&
1315 ddatptr->lastHighlightItem >= row + 1);
1316 } else {
1317 invert = (Boolean) (ddatptr->firstHighlightItem <= item + 1 &&
1318 ddatptr->lastHighlightItem >= item + 1);
1319 }
1320 gray = FALSE;
1321 if (grayProc != NULL && (! force)) {
1322 gray = grayProc (d, item + 1, row + 1, col + 1);
1323 }
1324 SelectFont (curFont);
1325 if (invert) {
1326 InvertColors ();
1327 EraseRect (&rct);
1328 }
1329 rct.left += insetLeft;
1330 rct.right -= insetRight;
1331 drw = rct;
1332 if (num > 0) {
1333 while (num > 0 && *ptr == '\t') {
1334 num--;
1335 ptr++;
1336 drw.left += CharWidth (' ') * tabCount;
1337 }
1338 if (ddatptr->drawcell != NULL) {
1339 tmp = (CharPtr) MemNew((size_t)(num + 2));
1340 if (tmp != NULL) {
1341 MemCopy (tmp, ptr, num);
1342 ddatptr->drawcell (d, item + 1, row + 1, col + 1, &drw, tmp, just, gray);
1343 MemFree (tmp);
1344 }
1345 } else {
1346 DrawText (&drw, ptr, num, just, gray);
1347 }
1348 }
1349 if (invert) {
1350 InvertColors ();
1351 }
1352 if (colorProc != NULL && (! force)) {
1353 SetColor (currentColor);
1354 }
1355 rct.left -= insetLeft;
1356 rct.right += insetRight;
1357 }
1358 }
1359 ptr += num;
1360 }
1361 ch = *ptr;
1362 }
1363 if (drawBars) {
1364 InvertMode ();
1365 for (col = 0; col < itemPtr->numCols; col++) {
1366 rct.left = colFmt [col].position;
1367 rct.right = rct.left + colFmt [col].pixWidth;
1368 if (colFmt [col].bar) {
1369 drawBars = TRUE;
1370 MoveTo (rct.left, barTop);
1371 /*
1372 #ifdef WIN_MAC
1373 LineTo (rct.left, barBottom -1);
1374 #else
1375 LineTo (rct.left, barBottom);
1376 #endif
1377 */
1378 if (is_old_win) {
1379 LineTo (rct.left, barBottom);
1380 } else {
1381 LineTo (rct.left, barBottom - 1);
1382 }
1383 }
1384 }
1385 CopyMode ();
1386 }
1387 rct.top = rct.bottom;
1388 rsult = rct.top - r->top;
1389 }
1390 SelectFont (systemFont);
1391 }
1392 return rsult;
1393 }
1394
1395 /*****************************************************************************
1396 *
1397 * DrawDocument (d)
1398 * Panel callback that traverses the item list and draws visible items
1399 * Clipping is to the intersection of the updateRgn (the portion of the
1400 * panel exposed) and the inset area of the document, leaving a four-
1401 * pixel margin
1402 *
1403 *****************************************************************************/
1404
1405 static void DrawDocument (PaneL d)
1406
1407 {
1408 DocData ddata;
1409 RegioN dst;
1410 Int4 firstLine;
1411 Int2 highest;
1412 Int2 item;
1413 ItemPtr itemPtr;
1414 Int2 lowest;
1415 Int2 numRows;
1416 Int4 off;
1417 Int2 pixels;
1418 RecT r;
1419 RecT rct;
1420 BaR sb;
1421 RegioN src;
1422
1423 GetPanelExtra (d, &ddata);
1424 if (ddata.numItems > 0) {
1425 ObjectRect (d, &r);
1426 InsetRect (&r, 4, 4);
1427 sb = GetSlateVScrollBar ((SlatE) d);
1428 if (sb != NULL) {
1429 src = CreateRgn ();
1430 dst = CreateRgn ();
1431 LoadRectRgn (src, r.left, r.top, r.right, r.bottom);
1432 SectRgn (src, updateRgn, dst);
1433 ClipRgn (dst);
1434 DestroyRgn (src);
1435 DestroyRgn (dst);
1436 off = GetBarValue (sb);
1437 pixels = 0;
1438 lowest = INT2_MAX;
1439 highest = INT2_MIN;
1440 item = GetItemNum (&ddata, off);
1441 itemPtr = GetItemPtr (&ddata, item);
1442 if (itemPtr != NULL) {
1443 firstLine = off - itemPtr->startsAt;
1444 do {
1445 if (itemPtr != NULL) {
1446 if (itemPtr->neverCached) {
1447 CollectRange (item, &lowest, &highest);
1448 }
1449 CacheAndFormat (&ddata, item + 1, itemPtr, &r, ddata.tabCount);
1450 SetTablePixFormat (itemPtr->colFmt, r.left, itemPtr->numCols);
1451 if (pixels != 0) {
1452 r.top += itemPtr->leadHeight;
1453 }
1454 rct = r;
1455 numRows = MIN (itemPtr->numRows - firstLine,
1456 MAX ((r.bottom - rct.top) / itemPtr->lineHeight, 0));
1457 rct.bottom = rct.top + itemPtr->lineHeight * (itemPtr->numRows - firstLine);
1458 if (updateRgn == NULL || RectInRgn (&rct, updateRgn)) {
1459 pixels = DrawTableItem ((DoC) d, &ddata, itemPtr, &r, item, firstLine,
1460 ddata.gray, ddata.invert, ddata.color,
1461 FALSE, ddata.tabCount);
1462 if (ddata.draw != NULL) {
1463 rct.bottom = rct.top + itemPtr->lineHeight * numRows;
1464 if (RectInRect (&rct, &r) &&
1465 (updateRgn == NULL || RectInRgn (&rct, updateRgn))) {
1466 ddata.draw ((DoC) d, &rct, item + 1, firstLine);
1467 }
1468 ResetDrawingTools ();
1469 }
1470 } else {
1471 pixels = rct.bottom - rct.top;
1472 }
1473 r.top += pixels;
1474 }
1475 item++;
1476 firstLine = 0;
1477 itemPtr = GetItemPtr (&ddata, item);
1478 } while (r.top < r.bottom && item < ddata.numItems && pixels > 0);
1479 if (lowest < INT2_MAX) {
1480 ddata.numLines = UpdateLineStarts (&ddata, lowest);
1481 SetPanelExtra (d, &ddata);
1482 }
1483 }
1484 ResetClip ();
1485 }
1486 }
1487 SelectFont (systemFont);
1488 }
1489
1490 /*****************************************************************************
1491 *
1492 * DocumentScrlProc (sb, s, newval, oldval)
1493 * Scroll bar callback that takes suppressed partial lines into account
1494 *
1495 *****************************************************************************/
1496
1497 static void DocumentScrlProc (BaR sb, SlatE s, Int4 newval, Int4 oldval)
1498
1499 {
1500 Int4 barmax;
1501 Int4 barval;
1502 DocData ddata;
1503 Int2 firstShown;
1504 Boolean goToEnd;
1505 Int2 height;
1506 Int2 highest;
1507 Int2 highFree;
1508 Int2 item;
1509 ItemPtr itemPtr;
1510 Int4 last;
1511 Int2 limit;
1512 Int2 line;
1513 Int2 lineInto;
1514 Int2 lowest;
1515 Int2 lowFree;
1516 Int4 min;
1517 Int2 pixels;
1518 Int2 pgDn;
1519 Int2 pgUp;
1520 RecT r;
1521 Int2 vis;
1522
1523 if (s != NULL && oldval != newval) {
1524 if (Visible (s) && AllParentsVisible (s)) {
1525 GetPanelExtra ((PaneL) s, &ddata);
1526 ObjectRect (s, &r);
1527 InsetRect (&r, 4, 4);
1528 height = r.bottom - r.top;
1529
1530 Select (s);
1531 if (ddata.pgUp < 1 || ddata.pgDn < 1) {
1532 InsetRect (&r, -1, -1);
1533 InvalRect (&r);
1534 } else if ((newval > oldval && newval <= oldval + ddata.pgDn) ||
1535 (newval < oldval && newval >= oldval - ddata.pgUp)) {
1536 pixels = PixelsBetween (&ddata, &r, newval, oldval, NULL, NULL);
1537 if (ABS (pixels) < height) {
1538 min = MIN (oldval, newval);
1539 item = GetItemNum (&ddata, min);
1540 line = (Int2) (min - GetStartsAt (&ddata, item));
1541 vis = VisLinesBelow (&ddata, &r, item, line, NULL, NULL);
1542 last = min + vis - 1;
1543 limit = PixelsBetween (&ddata, &r, newval, last, NULL, NULL);
1544 item = GetItemNum (&ddata, last);
1545 line = (Int2) (last - GetStartsAt (&ddata, item));
1546 limit += GetLineHeight (&ddata, item);
1547 ScrollRect (&r, 0, pixels);
1548 r.top += limit;
1549 InsetRect (&r, -1, -1);
1550 InvalRect (&r);
1551 } else {
1552 InsetRect (&r, -1, -1);
1553 InvalRect (&r);
1554 }
1555 } else {
1556 InsetRect (&r, -1, -1);
1557 InvalRect (&r);
1558 }
1559
1560 min = MIN (oldval, newval);
1561 item = GetItemNum (&ddata, min);
1562 ddata.numLines = UpdateLineStarts (&ddata, item);
1563 SetPanelExtra ((PaneL) s, &ddata);
1564
1565 item = GetItemNum (&ddata, newval);
1566 line = (Int2) (newval - GetStartsAt (&ddata, item));
1567 firstShown = item;
1568 lineInto = line;
1569
1570 barval = GetStartsAt (&ddata, firstShown) + lineInto;
1571 if (barval > ddata.barmax) {
1572 CorrectBarMax (sb, barval);
1573 CorrectBarValue (sb, barval);
1574 } else {
1575 CorrectBarValue (sb, barval);
1576 }
1577 Update ();
1578
1579 lowest = INT2_MAX;
1580 highest = INT2_MIN;
1581 ObjectRect (s, &r);
1582 InsetRect (&r, 4, 4);
1583 pgUp = VisLinesAbove (&ddata, &r, firstShown, lineInto, &lowest, &highest) - 1;
1584 pgDn = VisLinesBelow (&ddata, &r, firstShown, lineInto, &lowest, &highest) - 1;
1585 if (pgDn < 1) {
1586 pgDn = 1;
1587 }
1588 if (pgUp < 1) {
1589 pgUp = 1;
1590 }
1591 /*
1592 item = GetItemNum (&ddata, newval + pgDn);
1593 line = (Int2) (newval + (Int4) pgDn - GetStartsAt (&ddata, item));
1594 VisLinesBelow (&ddata, &r, item, line, &lowest, &highest);
1595 */
1596 if (lowest < INT2_MAX) {
1597 ddata.numLines = UpdateLineStarts (&ddata, lowest);
1598 SetPanelExtra ((PaneL) s, &ddata);
1599 }
1600
1601 lowFree = INT2_MAX;
1602 highFree = INT2_MIN;
1603 for (item = 0; item < lowest; item++) {
1604 FreeCachedItem (&ddata, item, &lowFree, &highFree);
1605 }
1606 for (item = highest + 1; item < ddata.numItems; item++) {
1607 FreeCachedItem (&ddata, item, &lowFree, &highFree);
1608 }
1609 if (lowFree < INT2_MAX) {
1610 ddata.numLines = UpdateLineStarts (&ddata, lowFree);
1611 SetPanelExtra ((PaneL) s, &ddata);
1612 }
1613
1614 barmax = 0;
1615 goToEnd = (Boolean) (newval == ddata.barmax);
1616 if (ddata.numLines > 0 && ddata.numItems > 0) {
1617 itemPtr = GetItemPtr (&ddata, ddata.numItems - 1);
1618 if (itemPtr != NULL) {
1619 ObjectRect (s, &r);
1620 InsetRect (&r, 4, 4);
1621 lowest = INT2_MAX;
1622 highest = INT2_MIN;
1623 vis = VisLinesAbove (&ddata, &r, ddata.numItems - 1,
1624 itemPtr->numRows - 1, &lowest, &highest);
1625 if (lowest < INT2_MAX) {
1626 ddata.numLines = UpdateLineStarts (&ddata, lowest);
1627 SetPanelExtra ((PaneL) s, &ddata);
1628 }
1629 barmax = ddata.numLines - vis;
1630 }
1631 }
1632 barval = GetStartsAt (&ddata, firstShown) + lineInto;
1633 if (goToEnd) {
1634 barval = barmax;
1635 }
1636 if (barval > ddata.barmax) {
1637 CorrectBarMax (sb, barmax);
1638 CorrectBarValue (sb, barval);
1639 } else {
1640 CorrectBarValue (sb, barval);
1641 CorrectBarMax (sb, barmax);
1642 }
1643 CorrectBarPage (sb, pgUp, pgDn);
1644 ddata.barmax = barmax;
1645 ddata.pgUp = pgUp;
1646 ddata.pgDn = pgDn;
1647 SetPanelExtra ((PaneL) s, &ddata);
1648 Update ();
1649 if (ddata.pan != NULL) {
1650 Select (s);
1651 ddata.pan ((DoC) s);
1652 }
1653 }
1654 }
1655 }
1656
1657 /*****************************************************************************
1658 *
1659 * CreateItemPtr (d, item)
1660 * Adds an item slot to the item list
1661 *
1662 *****************************************************************************/
1663
1664 static ItemPtr CreateItemPtr (DoC d, Int2 item)
1665
1666 {
1667 DocData ddata;
1668 Int2 index;
1669 Int2 list;
1670 ItemPtr itemPtr;
1671 ListDPtr listPtr;
1672 MasterPtr masterPtr;
1673
1674 itemPtr = NULL;
1675 if (d != NULL && item < 32767) {
1676 GetPanelExtra ((PaneL) d, &ddata);
1677 if (ddata.master == NULL) {
1678 ddata.master = (MasterPtr) MemNew (sizeof (MasterData));
1679 SetPanelExtra ((PaneL) d, &ddata);
1680 }
1681 list = (item / LISTSIZE);
1682 if (list < MAXLISTS && ddata.master != NULL) {
1683 masterPtr = ddata.master;
1684 listPtr = masterPtr->list [list];
1685 if (listPtr == NULL) {
1686 masterPtr->list [list] = (ListDPtr) MemNew(sizeof(ListData));
1687 listPtr = masterPtr->list [list];
1688 }
1689 if (listPtr != NULL) {
1690 index = (item % LISTSIZE);
1691 itemPtr = &(listPtr->items [index]);
1692 }
1693 }
1694 }
1695 return itemPtr;
1696 }
1697
1698 /*****************************************************************************
1699 *
1700 * GetFontHeight (font)
1701 * Returns the pixel height of a font, caching for quicker access
1702 *
1703 *****************************************************************************/
1704
1705 static Int2 GetFontHeight (FonT font)
1706
1707 {
1708 Int2 height;
1709 Int2 i;
1710
1711 height = 0;
1712 i = 0;
1713 while (i < MAXFONTS && fontHeights [i].font != font && fontHeights [i].font != NULL) {
1714 i++;
1715 }
1716 if (fontHeights [i].font == font) {
1717 height = fontHeights [i].height;
1718 } else {
1719 SelectFont (font);
1720 height = LineHeight ();
1721 if (i < MAXFONTS) {
1722 fontHeights [i].font = font;
1723 fontHeights [i].height = height;
1724 }
1725 }
1726 return height;
1727 }
1728
1729 /*****************************************************************************
1730 *
1731 * UpdateItemHeights (itemPtr)
1732 * Returns the maximum height of all fonts used in an item
1733 *
1734 *****************************************************************************/
1735
1736 static void UpdateItemHeights (ItemPtr itemPtr)
1737
1738 {
1739 ColXPtr colFmt;
1740 FonT fnt;
1741 Int2 i;
1742 Int2 linhgt;
1743 Int2 maxhgt;
1744
1745 if (itemPtr != NULL) {
1746 colFmt = itemPtr->colFmt;
1747 maxhgt = 0;
1748 if (colFmt != NULL) {
1749 i = itemPtr->numCols;
1750 while (i > 0) {
1751 i--;
1752 fnt = colFmt [i].font;
1753 if (fnt != NULL) {
1754 linhgt = GetFontHeight (fnt);
1755 if (linhgt > maxhgt) {
1756 maxhgt = linhgt;
1757 }
1758 } else if (itemPtr->font == NULL) {
1759 linhgt = stdLineHeight;
1760 if (linhgt > maxhgt) {
1761 maxhgt = linhgt;
1762 }
1763 }
1764 }
1765 }
1766 fnt = itemPtr->font;
1767 if (fnt != NULL) {
1768 linhgt = GetFontHeight (fnt);
1769 if (linhgt > maxhgt) {
1770 maxhgt = linhgt;
1771 }
1772 }
1773 if (maxhgt == 0) {
1774 maxhgt = stdLineHeight;
1775 }
1776 itemPtr->lineHeight = MAX (maxhgt, itemPtr->minHeight);
1777 if (itemPtr->openSpace) {
1778 itemPtr->leadHeight = maxhgt;
1779 } else {
1780 itemPtr->leadHeight = 0;
1781 }
1782 }
1783 }
1784
1785 /*****************************************************************************
1786 *
1787 * SetDocAutoAdjust (d, autoAdjust)
1788 * Sets the document automatic scroll adjust parameter
1789 *
1790 *****************************************************************************/
1791
1792 extern void SetDocAutoAdjust (DoC d, Boolean autoAdjust)
1793
1794 {
1795 DocData ddata;
1796
1797 if (d != NULL) {
1798 GetPanelExtra ((PaneL) d, &ddata);
1799 ddata.autoAdjust = autoAdjust;
1800 SetPanelExtra ((PaneL) d, &ddata);
1801 }
1802 }
1803
1804 /* dgg here -- want to make use of tab settings other than from FancyFile call */
1805
1806 /*****************************************************************************
1807 *
1808 * Nlm_SetDocTabstops (d, tabStops)
1809 * Sets the document tap stop interval
1810 *
1811 *****************************************************************************/
1812
1813 extern void Nlm_SetDocTabstops (DoC d, Int2 tabStops)
1814 {
1815 DocData ddata;
1816
1817 if (d != NULL) {
1818 GetPanelExtra ((PaneL) d, &ddata);
1819 ddata.tabCount = tabStops;
1820 SetPanelExtra ((PaneL) d, &ddata);
1821 }
1822 }
1823
1824 /*****************************************************************************
1825 *
1826 * AdjustDocScroll (d)
1827 * Calculates an estimate for the scroll bar maximum
1828 *
1829 *****************************************************************************/
1830
1831 extern void AdjustDocScroll (DoC d)
1832
1833 {
1834 Int4 barmax;
1835 Int4 barval;
1836 DocData ddata;
1837 Int2 firstShown;
1838 Int2 highest;
1839 Int2 item;
1840 ItemPtr itemPtr;
1841 Int2 line;
1842 Int2 lineInto;
1843 Int2 lowest;
1844 Int2 pgDn;
1845 Int2 pgUp;
1846 RecT r;
1847 BaR sb;
1848 Int2 vis;
1849
1850 if (d != NULL) {
1851 GetPanelExtra ((PaneL) d, &ddata);
1852 SelectFont (systemFont);
1853 sb = GetSlateVScrollBar ((SlatE) d);
1854 if (sb != NULL) {
1855 if (ddata.numLines > 0 && ddata.numItems > 0) {
1856 ObjectRect (d, &r);
1857 InsetRect (&r, 4, 4);
1858 barval = GetBarValue (sb);
1859 item = GetItemNum (&ddata, barval);
1860 line = (Int2) (barval - GetStartsAt (&ddata, item));
1861 firstShown = item;
1862 lineInto = line;
1863 lowest = INT2_MAX;
1864 highest = INT2_MIN;
1865 itemPtr = GetItemPtr (&ddata, ddata.numItems - 1);
1866 if (itemPtr != NULL) {
1867 CacheIfNever (&ddata, ddata.numItems, itemPtr, &r, ddata.tabCount);
1868 vis = VisLinesAbove (&ddata, &r, ddata.numItems - 1,
1869 itemPtr->numRows - 1, &lowest, &highest);
1870 }
1871 pgUp = VisLinesAbove (&ddata, &r, firstShown, lineInto, &lowest, &highest) - 1;
1872 pgDn = VisLinesBelow (&ddata, &r, firstShown, lineInto, &lowest, &highest) - 1;
1873 if (pgDn < 1) {
1874 pgDn = 1;
1875 }
1876 if (pgUp < 1) {
1877 pgUp = 1;
1878 }
1879 /*
1880 item = GetItemNum (&ddata, barval + pgDn);
1881 line = (Int2) (barval + (Int4) pgDn - GetStartsAt (&ddata, item));
1882 VisLinesBelow (&ddata, &r, item, line, &lowest, &highest);
1883 */
1884 if (lowest < INT2_MAX) {
1885 ddata.numLines = UpdateLineStarts (&ddata, lowest);
1886 SetPanelExtra ((PaneL) d, &ddata);
1887 }
1888 itemPtr = GetItemPtr (&ddata, ddata.numItems - 1);
1889 if (itemPtr != NULL) {
1890 barmax = 0;
1891 ObjectRect (d, &r);
1892 InsetRect (&r, 4, 4);
1893 lowest = INT2_MAX;
1894 highest = INT2_MIN;
1895 vis = VisLinesAbove (&ddata, &r, ddata.numItems - 1,
1896 itemPtr->numRows - 1, &lowest, &highest);
1897 if (lowest < INT2_MAX) {
1898 ddata.numLines = UpdateLineStarts (&ddata, lowest);
1899 SetPanelExtra ((PaneL) d, &ddata);
1900 }
1901 barmax = ddata.numLines - vis;
1902 barval = GetStartsAt (&ddata, firstShown) + lineInto;
1903 CorrectBarPage (sb, pgUp, pgDn);
1904 if (barval > ddata.barmax) {
1905 CorrectBarMax (sb, barmax);
1906 CorrectBarValue (sb, barval);
1907 } else {
1908 CorrectBarValue (sb, barval);
1909 CorrectBarMax (sb, barmax);
1910 }
1911 ddata.barmax = barmax;
1912 ddata.pgUp = pgUp;
1913 ddata.pgDn = pgDn;
1914 SetPanelExtra ((PaneL) d, &ddata);
1915 }
1916 } else {
1917 Reset (sb);
1918 }
1919 }
1920 }
1921 }
1922
1923 /*****************************************************************************
1924 *
1925 * ForceFormat (d, item)
1926 * Forces text format
1927 *
1928 *****************************************************************************/
1929
1930 extern void ForceFormat (DoC d, Int2 item)
1931
1932 {
1933 DocData ddata;
1934 ItemPtr itemPtr;
1935 RecT r;
1936
1937 if (d != NULL && item > 0) {
1938 GetPanelExtra ((PaneL) d, &ddata);
1939 itemPtr = GetItemPtr (&ddata, item - 1);
1940 if (itemPtr != NULL) {
1941 ObjectRect (d, &r);
1942 InsetRect (&r, 4, 4);
1943 itemPtr->text = (CharPtr) MemFree (itemPtr->text);
1944 itemPtr->notCached = TRUE;
1945 itemPtr->neverCached = TRUE;
1946 SetTablePixFormat (itemPtr->colFmt, r.left, itemPtr->numCols);
1947 FormatText (&ddata, item, itemPtr, TRUE, ddata.tabCount);
1948 UpdateItemHeights (itemPtr);
1949 ddata.numLines = UpdateLineStarts (&ddata, 0);
1950 SetPanelExtra ((PaneL) d, &ddata);
1951 if (ddata.autoAdjust) {
1952 AdjustDocScroll (d);
1953 }
1954 }
1955 }
1956 }
1957
1958 /*****************************************************************************
1959 *
1960 * defaultTable
1961 * Column format used if the colFmt parameter is NULL
1962 *
1963 *****************************************************************************/
1964
1965 static ColData defaultTable = {0, 0, 0, 0, NULL, 'l',
1966 TRUE, FALSE, FALSE, FALSE, TRUE};
1967
1968 /*****************************************************************************
1969 *
1970 * CacheColFmt (d, colFmt)
1971 * Caches the colFmt format structure
1972 *
1973 *****************************************************************************/
1974
1975 static ColXPtr CacheColFmt (DoC d, ColPtr colFmt)
1976
1977 {
1978 DocData ddata;
1979 Boolean found;
1980 Boolean goOn;
1981 Int2 i;
1982 Int2 numCols;
1983 ColXPtr rsult;
1984 ColXPtr thisCol;
1985 ValNodePtr vnp;
1986
1987 rsult = NULL;
1988 if (d != NULL && colFmt != NULL) {
1989 i = 0;
1990 while (! colFmt [i].last) {
1991 i++;
1992 }
1993 i++;
1994 numCols = i;
1995 rsult = (ColXPtr) MemNew (numCols * sizeof (ColXData));
1996 if (rsult != NULL) {
1997 for (i = 0; i < numCols; i++) {
1998 rsult [i].position = 0;
1999 rsult [i].pixWidth = colFmt [i].pixWidth;
2000 rsult [i].pixInset = colFmt [i].pixInset;
2001 rsult [i].charWidth = colFmt [i].charWidth;
2002 rsult [i].charInset = colFmt [i].charInset;
2003 if (colFmt [i].just == 'l') {
2004 rsult [i].just = JUST_LEFT;
2005 } else if (colFmt [i].just == 'c') {
2006 rsult [i].just = JUST_CENTER;
2007 } else if (colFmt [i].just == 'r') {
2008 rsult [i].just = JUST_RIGHT;
2009 } else {
2010 rsult [i].just = JUST_LEFT;
2011 }
2012 rsult [i].font = colFmt [i].font;
2013 rsult [i].zeroWidth = (Boolean) (colFmt [i].pixWidth == 0);
2014 if (rsult [i].zeroWidth) {
2015 rsult [i].charWidth = 0;
2016 }
2017 rsult [i].wrap = colFmt [i].wrap;
2018 rsult [i].bar = colFmt [i].bar;
2019 rsult [i].underline = colFmt [i].underline;
2020 rsult [i].left = colFmt [i].left;
2021 rsult [i].last = colFmt [i].last;
2022 }
2023 GetPanelExtra ((PaneL) d, &ddata);
2024 vnp = ddata.colFmts;
2025 goOn = TRUE;
2026 while (vnp != NULL && goOn) {
2027 thisCol = (ColXPtr) vnp->data.ptrvalue;
2028 if (thisCol != NULL) {
2029 i = 0;
2030 while (! thisCol [i].last) {
2031 i++;
2032 }
2033 i++;
2034 if (i == numCols) {
2035 found = TRUE;
2036 for (i = 0; i < numCols; i++) {
2037 if (thisCol [i].zeroWidth) {
2038 thisCol [i].pixWidth = 0;
2039 thisCol [i].charWidth = 0;
2040 }
2041 if (thisCol [i].font != rsult [i].font ||
2042 thisCol [i].pixWidth != rsult [i].pixWidth ||
2043 thisCol [i].pixInset != rsult [i].pixInset ||
2044 thisCol [i].charWidth != rsult [i].charWidth ||
2045 thisCol [i].charInset != rsult [i].charInset ||
2046 thisCol [i].just != rsult [i].just ||
2047 thisCol [i].zeroWidth != rsult [i].zeroWidth ||
2048 thisCol [i].wrap != rsult [i].wrap ||
2049 thisCol [i].bar != rsult [i].bar ||
2050 thisCol [i].underline != rsult [i].underline ||
2051 thisCol [i].left != rsult [i].left ||
2052 thisCol [i].last != rsult [i].last) {
2053 found = FALSE;
2054 }
2055 }
2056 if (found) {
2057 goOn = FALSE;
2058 }
2059 }
2060 }
2061 if (goOn) {
2062 vnp = vnp->next;
2063 }
2064 }
2065 if (goOn) {
2066 vnp = ValNodeNew (ddata.colFmts);
2067 if (vnp != NULL) {
2068 vnp->data.ptrvalue = (Pointer) rsult;
2069 }
2070 if (ddata.colFmts == NULL) {
2071 ddata.colFmts = vnp;
2072 SetPanelExtra ((PaneL) d, &ddata);
2073 }
2074 } else {
2075 MemFree (rsult);
2076 rsult = (ColXPtr) vnp->data.ptrvalue;
2077 }
2078 }
2079 }
2080 return rsult;
2081 }
2082
2083 /*****************************************************************************
2084 *
2085 * UpdateColFmt (d, *col)
2086 * Returns the maximum height of all fonts used in an item
2087 *
2088 *****************************************************************************/
2089
2090 extern void UpdateColFmt (DoC d, ColPtr col)
2091
2092 {
2093 DocData dd;
2094 ItemPtr itemPtr;
2095 Int2 item;
2096
2097 GetPanelExtra ((PaneL) d, &dd);
2098 for (item = 0; item < dd.numItems; item++) {
2099 itemPtr = GetItemPtr (&dd, item);
2100 if (itemPtr != NULL) {
2101 itemPtr->colFmt = CacheColFmt (d, col);
2102 }
2103 }
2104 SetPanelExtra ((PaneL) d, &dd);
2105 }
2106
2107 /*****************************************************************************
2108 *
2109 * SetDocDefaults (d, defaultParFmt, defaultColFmt, defaultFont)
2110 * Sets default format preferences, so AppendItem, etc., can pass NULLs
2111 *
2112 *****************************************************************************/
2113
2114 extern void SetDocDefaults (DoC d, ParPtr defaultParFmt,
2115 ColPtr defaultColFmt, FonT defaultFont)
2116
2117 {
2118 DocData ddata;
2119
2120 if (d != NULL) {
2121 GetPanelExtra ((PaneL) d, &ddata);
2122 ddata.defaultParFmt = defaultParFmt;
2123 ddata.defaultColFmt = defaultColFmt;
2124 ddata.defaultFont = defaultFont;
2125 SetPanelExtra ((PaneL) d, &ddata);
2126 }
2127 }
2128
2129 /*****************************************************************************
2130 *
2131 * SetDocSimpleMode (d, useRowsNotItems)
2132 * Sets default highlighting range
2133 *
2134 *****************************************************************************/
2135
2136 extern void SetDocSimpleMode (DoC d, Boolean useRowsNotItems)
2137
2138 {
2139 DocData ddata;
2140
2141 if (d != NULL) {
2142 GetPanelExtra ((PaneL) d, &ddata);
2143 ddata.useRowsNotItems = useRowsNotItems;
2144 SetPanelExtra ((PaneL) d, &ddata);
2145 }
2146 }
2147 /*****************************************************************************
2148 *
2149 * SetDocHighlight (d, firstItem, lastItem)
2150 * Sets default highlighting range
2151 *
2152 *****************************************************************************/
2153
2154 extern void SetDocHighlight (DoC d, Int2 firstItem, Int2 lastItem)
2155
2156 {
2157 DocData ddata;
2158
2159 if (d != NULL) {
2160 GetPanelExtra ((PaneL) d, &ddata);
2161 ddata.firstHighlightItem = MIN (firstItem, lastItem);
2162 ddata.lastHighlightItem = MAX (firstItem, lastItem);
2163 SetPanelExtra ((PaneL) d, &ddata);
2164 }
2165 }
2166
2167 /*****************************************************************************
2168 *
2169 * GetDocHighlight (d, firstItem, lastItem)
2170 * Returns default highlighting range
2171 *
2172 *****************************************************************************/
2173
2174 extern void GetDocHighlight (DoC d, Int2Ptr firstItem, Int2Ptr lastItem)
2175
2176 {
2177 DocData ddata;
2178
2179 if (d != NULL) {
2180 GetPanelExtra ((PaneL) d, &ddata);
2181 if (firstItem != NULL) {
2182 *firstItem = ddata.firstHighlightItem;
2183 }
2184 if (lastItem != NULL) {
2185 *lastItem = ddata.lastHighlightItem;
2186 }
2187 }
2188 }
2189
2190 /*****************************************************************************
2191 *
2192 * SetDocNotify (d, notify)
2193 * Sets default click notification
2194 *
2195 *****************************************************************************/
2196
2197 static void DefaultNotifyClickProc (DoC d, PoinT pt)
2198
2199 {
2200 Int2 col;
2201 DocData ddata;
2202 Int2 item;
2203 Int2 row;
2204
2205 if (d != NULL) {
2206 GetPanelExtra ((PaneL) d, &ddata);
2207 if (ddata.notify != NULL) {
2208 MapDocPoint (d, pt, &item, &row, &col, NULL);
2209 ddata.notify (d, item, row, col, dblClick);
2210 }
2211 }
2212 }
2213
2214 extern void SetDocNotify (DoC d, DocNotfyProc notify)
2215
2216 {
2217 DocData ddata;
2218
2219 if (d != NULL) {
2220 GetPanelExtra ((PaneL) d, &ddata);
2221 ddata.notify = notify;
2222 SetPanelExtra ((PaneL) d, &ddata);
2223 Nlm_SetPanelClick ((PaneL) d, (PnlClckProc) DefaultNotifyClickProc, NULL, NULL, NULL);
2224 }
2225 }
2226
2227 /*****************************************************************************
2228 *
2229 * SetupItem (d, ddatptr, itemPtr, proc, data, docOwnsData,
2230 * lines, parFmt, colFmt, font)
2231 * Processes user parameters into an item to append or insert into
2232 * the item list, or replace an item currently in the item list
2233 *
2234 *****************************************************************************/
2235
2236 static void SetupItem (DoC d, DocDataPtr ddatptr, ItemPtr itemPtr, DocPrntProc proc,
2237 Pointer data, Boolean docOwnsData, Int2 lines,
2238 ParPtr parFmt, ColPtr colFmt, FonT font)
2239
2240 {
2241 Int2 i;
2242 RecT r;
2243
2244 if (d != NULL && ddatptr != NULL && itemPtr != NULL && proc != NULL) {
2245 ObjectRect (d, &r);
2246 InsetRect (&r, 4, 4);
2247 itemPtr->prtProc = proc;
2248 itemPtr->dataPtr = data;
2249 itemPtr->text = NULL;
2250 if (font == NULL) {
2251 font = ddatptr->defaultFont;
2252 }
2253 itemPtr->font = font;
2254 if (colFmt == NULL) {
2255 colFmt = ddatptr->defaultColFmt;
2256 }
2257 if (colFmt == NULL) {
2258 defaultTable.pixWidth = r.right - r.left;
2259 defaultTable.charWidth = 80;
2260 colFmt = &defaultTable;
2261 }
2262 i = 0;
2263 while (! colFmt [i].last) {
2264 i++;
2265 }
2266 i++;
2267 itemPtr->numCols = i;
2268 itemPtr->numRows = MAX (lines, 1);
2269 itemPtr->colFmt = CacheColFmt (d, colFmt);
2270 itemPtr->extra = NULL;
2271 itemPtr->startsAt = 0;
2272 if (parFmt == NULL) {
2273 parFmt = ddatptr->defaultParFmt;
2274 }
2275 if (parFmt != NULL) {
2276 itemPtr->openSpace = parFmt->openSpace;
2277 itemPtr->keepWithNext = parFmt->keepWithNext;
2278 itemPtr->keepTogether = parFmt->keepTogether;
2279 itemPtr->newPage = parFmt->newPage;
2280 itemPtr->tabStops = parFmt->tabStops;
2281 itemPtr->minLines = MAX (parFmt->minLines, (Int2) 1);
2282 itemPtr->minHeight = parFmt->minHeight;
2283 } else {
2284 itemPtr->openSpace = TRUE;
2285 itemPtr->keepWithNext = FALSE;
2286 itemPtr->keepTogether = FALSE;
2287 itemPtr->newPage = FALSE;
2288 itemPtr->tabStops = FALSE;
2289 itemPtr->minLines = 0;
2290 itemPtr->minHeight = 0;
2291 }
2292 itemPtr->docOwnsData = docOwnsData;
2293 itemPtr->notCached = TRUE;
2294 itemPtr->neverCached = TRUE;
2295 }
2296 }
2297
2298 /*****************************************************************************
2299 *
2300 * AppendItem (d, proc, data, docOwnsData, lines,
2301 * parFmt, colFmt, font)
2302 * Processes user parameters and appends the item to the end of the
2303 * item list
2304 *
2305 *****************************************************************************/
2306
2307 extern void AppendItem (DoC d, DocPrntProc proc, Pointer data,
2308 Boolean docOwnsData, Int2 lines,
2309 ParPtr parFmt, ColPtr colFmt, FonT font)
2310
2311 {
2312 DocData ddata;
2313 ItemData itemData;
2314 ItemPtr itemPtr;
2315
2316 if (d != NULL && proc != NULL) {
2317 GetPanelExtra ((PaneL) d, &ddata);
2318 MemFill (&itemData, 0, sizeof (ItemData));
2319 SetupItem (d, &ddata, &itemData, proc, data, docOwnsData,
2320 lines, parFmt, colFmt, font);
2321 if (ddata.upd != NULL) {
2322 ddata.upd (d, ddata.numItems, 0);
2323 }
2324 itemPtr = CreateItemPtr (d, ddata.numItems);
2325 GetPanelExtra ((PaneL) d, &ddata);
2326 if (itemPtr != NULL) {
2327 *itemPtr = *(&itemData);
2328 itemPtr->startsAt = ddata.numLines;
2329 UpdateItemHeights (itemPtr);
2330 ddata.numLines += itemPtr->numRows;
2331 (ddata.numItems)++;
2332 SetPanelExtra ((PaneL) d, &ddata);
2333 if (ddata.autoAdjust) {
2334 AdjustDocScroll (d);
2335 }
2336 }
2337 }
2338 }
2339
2340 /*****************************************************************************
2341 *
2342 * ReplaceItem (d, item, proc, data, docOwnsData,
2343 * lines, parFmt, colFmt, font)
2344 * Replaces an existing item in a document
2345 *
2346 *****************************************************************************/
2347
2348 extern void ReplaceItem (DoC d, Int2 item, DocPrntProc proc,
2349 Pointer data, Boolean docOwnsData, Int2 lines,
2350 ParPtr parFmt, ColPtr colFmt, FonT font)
2351
2352 {
2353 DocData ddata;
2354 ItemPtr itemPtr;
2355 Int4 startsAt;
2356
2357 if (d != NULL && proc != NULL) {
2358 GetPanelExtra ((PaneL) d, &ddata);
2359 if (item > 0 && item <= ddata.numItems) {
2360 item--;
2361 if (ddata.upd != NULL) {
2362 ddata.upd (d, item, item);
2363 }
2364 itemPtr = GetItemPtr (&ddata, item);
2365 if (itemPtr != NULL) {
2366 startsAt = itemPtr->startsAt;
2367 itemPtr->text = (CharPtr) MemFree (itemPtr->text);
2368 if (itemPtr->docOwnsData) {
2369 itemPtr->dataPtr = (Pointer) MemFree (itemPtr->dataPtr);
2370 } else {
2371 itemPtr->dataPtr = NULL;
2372 }
2373 itemPtr->extra = MemFree (itemPtr->extra);
2374 MemFill (itemPtr, 0, sizeof (ItemData));
2375 SetupItem (d, &ddata, itemPtr, proc, data, docOwnsData,
2376 lines, parFmt, colFmt, font);
2377 itemPtr->startsAt = startsAt;
2378 UpdateItemHeights (itemPtr);
2379 ddata.numLines = UpdateLineStarts (&ddata, item);
2380 SetPanelExtra ((PaneL) d, &ddata);
2381 if (ddata.autoAdjust) {
2382 AdjustDocScroll (d);
2383 }
2384 }
2385 }
2386 }
2387 }
2388
2389 /*****************************************************************************
2390 *
2391 * InsertItem (d, item, proc, data, docOwnsData,
2392 * lines, parFmt, colFmt, font)
2393 * Inserts a new item into a document
2394 *
2395 *****************************************************************************/
2396
2397 extern void InsertItem (DoC d, Int2 item, DocPrntProc proc,
2398 Pointer data, Boolean docOwnsData, Int2 lines,
2399 ParPtr parFmt, ColPtr colFmt, FonT font)
2400
2401 {
2402 DocData ddata;
2403 ItemPtr fromItem;
2404 ItemPtr itemPtr;
2405 Int2 j;
2406 Int4 startsAt;
2407 ItemPtr toItem;
2408
2409 if (d != NULL && proc != NULL) {
2410 GetPanelExtra ((PaneL) d, &ddata);
2411 if (item > 0 && item <= ddata.numItems) {
2412 item--;
2413 if (ddata.upd != NULL) {
2414 ddata.upd (d, item, 0);
2415 }
2416 itemPtr = CreateItemPtr (d, ddata.numItems);
2417 if (itemPtr != NULL) {
2418 GetPanelExtra ((PaneL) d, &ddata);
2419 (ddata.numItems)++;
2420 SetPanelExtra ((PaneL) d, &ddata);
2421 for (j = ddata.numItems - 1; j > item; j--) {
2422 fromItem = GetItemPtr (&ddata, j - 1);
2423 toItem = GetItemPtr (&ddata, j);
2424 if (fromItem != NULL && toItem != NULL) {
2425 *toItem = *fromItem;
2426 }
2427 }
2428 itemPtr = GetItemPtr (&ddata, item);
2429 if (itemPtr != NULL) {
2430 startsAt = itemPtr->startsAt;
2431 MemFill (itemPtr, 0, sizeof (ItemData));
2432 SetupItem (d, &ddata, itemPtr, proc, data, docOwnsData,
2433 lines, parFmt, colFmt, font);
2434 itemPtr->startsAt = startsAt;
2435 UpdateItemHeights (itemPtr);
2436 ddata.numLines = UpdateLineStarts (&ddata, item);
2437 SetPanelExtra ((PaneL) d, &ddata);
2438 if (ddata.autoAdjust) {
2439 AdjustDocScroll (d);
2440 }
2441 }
2442 }
2443 }
2444 }
2445 }
2446
2447 /*****************************************************************************
2448 *
2449 * CharPrtProc (ptr)
2450 * Standard print function used with AppendText
2451 *
2452 *****************************************************************************/
2453
2454 static CharPtr CharPrtProc (DoC d, Int2 item, Pointer ptr)
2455
2456 {
2457 if (ptr != NULL) {
2458 return StringSave( (CharPtr)ptr );
2459 } else {
2460 return NULL;
2461 }
2462 }
2463
2464 /*****************************************************************************
2465 *
2466 * SkipPastNewLine (text, cnt)
2467 * Finds the end of a line of text, up to a maximum number of characters
2468 *
2469 *****************************************************************************/
2470
2471 static Int2 SkipPastNewLine (CharPtr text, Int2 cnt)
2472
2473 {
2474 Char ch;
2475
2476 ch = *(text + cnt);
2477 while (ch != '\0' && ch != '\n' && cnt < 24380) {
2478 cnt++;
2479 ch = *(text + cnt);
2480 }
2481 while ((ch == '\n' || ch == '\r') && cnt < 24380) {
2482 cnt++;
2483 ch = *(text + cnt);
2484 }
2485 return cnt;
2486 }
2487
2488 /*****************************************************************************
2489 *
2490 * AppendText (d, text, parFmt, colFmt, font)
2491 * Special case of AppendItem that takes formatted text as its data
2492 *
2493 *****************************************************************************/
2494
2495 extern void AppendText (DoC d, CharPtr text, ParPtr parFmt,
2496 ColPtr colFmt, FonT font)
2497
2498 {
2499 Int2 cnt;
2500 Int2 cntr;
2501 Int2 start;
2502 Pointer txt;
2503
2504 if (d != NULL) {
2505 if (text != NULL && *text != '\0') {
2506 start = 0;
2507 cntr = StringLen (text);
2508 cnt = MIN (cntr, 24000);
2509 cnt = SkipPastNewLine (text + start, cnt);
2510 while (cnt > 0) {
2511 txt = MemNew (cnt + 1);
2512 MemCopy (txt, text + start, cnt);
2513 ProgMon ("AppendText");
2514 AppendItem (d, CharPrtProc, txt, TRUE, (cnt / 50) + 1,
2515 parFmt, colFmt, font);
2516 start += cnt;
2517 cntr -= cnt;
2518 cnt = MIN (cntr, 24000);
2519 cnt = SkipPastNewLine (text + start, cnt);
2520 }
2521 } else {
2522 ProgMon ("AppendText");
2523 AppendItem (d, CharPrtProc, "", FALSE, 1,
2524 parFmt, colFmt, font);
2525 }
2526 }
2527 }
2528
2529 /*****************************************************************************
2530 *
2531 * ReplaceText (d, item, text, parFmt, colFmt, font)
2532 * Special case of ReplaceItem that takes formatted text as its data
2533 *
2534 *****************************************************************************/
2535
2536 extern void ReplaceText (DoC d, Int2 item, CharPtr text,
2537 ParPtr parFmt, ColPtr colFmt, FonT font)
2538
2539 {
2540 Int2 cnt;
2541 Int2 cntr;
2542 Int2 start;
2543 Pointer txt;
2544
2545 if (d != NULL) {
2546 if (text != NULL && *text != '\0') {
2547 start = 0;
2548 cntr = StringLen (text);
2549 cnt = MIN (cntr, 24000);
2550 cnt = SkipPastNewLine (text + start, cnt);
2551 while (cnt > 0) {
2552 txt = MemNew (cnt + 1);
2553 MemCopy (txt, text + start, cnt);
2554 ReplaceItem (d, item, CharPrtProc, txt, TRUE, (cnt / 50) + 1,
2555 parFmt, colFmt, font);
2556 start += cnt;
2557 cntr -= cnt;
2558 cnt = MIN (cntr, 24000);
2559 cnt = SkipPastNewLine (text + start, cnt);
2560 item++;
2561 }
2562 } else {
2563 ReplaceItem (d, item, CharPrtProc, "", FALSE, 1,
2564 parFmt, colFmt, font);
2565 }
2566 }
2567 }
2568
2569 /*****************************************************************************
2570 *
2571 * InsertText (d, item, text, parFmt, colFmt, font)
2572 * Special case of InsertItem that takes formatted text as its data
2573 *
2574 *****************************************************************************/
2575
2576 extern void InsertText (DoC d, Int2 item, CharPtr text,
2577 ParPtr parFmt, ColPtr colFmt, FonT font)
2578
2579 {
2580 Int2 cnt;
2581 Int2 cntr;
2582 Int2 start;
2583 Pointer txt;
2584
2585 if (d != NULL) {
2586 if (text != NULL && *text != '\0') {
2587 start = 0;
2588 cntr = StringLen (text);
2589 cnt = MIN (cntr, 24000);
2590 cnt = SkipPastNewLine (text + start, cnt);
2591 while (cnt > 0) {
2592 txt = MemNew (cnt + 1);
2593 MemCopy (txt, text + start, cnt);
2594 InsertItem (d, item, CharPrtProc, txt, TRUE, (cnt / 50) + 1,
2595 parFmt, colFmt, font);
2596 start += cnt;
2597 cntr -= cnt;
2598 cnt = MIN (cntr, 24000);
2599 cnt = SkipPastNewLine (text + start, cnt);
2600 item++;
2601 }
2602 } else {
2603 InsertItem (d, item, CharPrtProc, "", FALSE, 1,
2604 parFmt, colFmt, font);
2605 }
2606 }
2607 }
2608
2609 /*****************************************************************************
2610 *
2611 * DeleteItem (d, item)
2612 * Deletes an item from a document
2613 *
2614 *****************************************************************************/
2615
2616 extern void DeleteItem (DoC d, Int2 item)
2617
2618 {
2619 DocData ddata;
2620 ItemPtr fromItem;
2621 ItemPtr itemPtr;
2622 Int2 j;
2623 Int4 startsAt;
2624 ItemPtr toItem;
2625
2626 if (d != NULL) {
2627 GetPanelExtra ((PaneL) d, &ddata);
2628 if (item > 0 && item <= ddata.numItems) {
2629 item--;
2630 itemPtr = GetItemPtr (&ddata, item);
2631 if (itemPtr != NULL) {
2632 startsAt = itemPtr->startsAt;
2633 itemPtr->text = (CharPtr) MemFree (itemPtr->text);
2634 if (itemPtr->docOwnsData) {
2635 itemPtr->dataPtr = (Pointer) MemFree (itemPtr->dataPtr);
2636 } else {
2637 itemPtr->dataPtr = NULL;
2638 }
2639 itemPtr->extra = MemFree (itemPtr->extra);
2640 for (j = item; j < ddata.numItems - 1; j++) {
2641 fromItem = GetItemPtr (&ddata, j + 1);
2642 toItem = GetItemPtr (&ddata, j);
2643 if (fromItem != NULL && toItem != NULL) {
2644 *toItem = *fromItem;
2645 }
2646 }
2647 itemPtr->startsAt = startsAt;
2648 (ddata.numItems)--;
2649 ddata.numLines = UpdateLineStarts (&ddata, item);
2650 SetPanelExtra ((PaneL) d, &ddata);
2651 if (ddata.autoAdjust) {
2652 AdjustDocScroll (d);
2653 }
2654 }
2655 }
2656 }
2657 }
2658
2659 /*****************************************************************************
2660 *
2661 * BulkAppendItem (d, numItems, proc, estLines, parFmt, colFmt, font)
2662 * Populates a document in one step, assuming that the print function
2663 * doesn't need individual data
2664 *
2665 *****************************************************************************/
2666
2667 extern void BulkAppendItem (DoC d, Int2 numItems, DocPrntProc proc,
2668 Int2 estLines, ParPtr parFmt,
2669 ColPtr colFmt, FonT font)
2670
2671 {
2672 ColXPtr colXPtr;
2673 DocData ddata;
2674 Int2 i;
2675 Int2 index;
2676 Int2 item;
2677 ItemPtr itemPtr;
2678 Int2 leadHeight = 0;
2679 Int2 lineHeight = stdLineHeight;
2680 Int2 list;
2681 ListDPtr listPtr;
2682 MasterPtr masterPtr;
2683 Int2 numCols;
2684 Int2 numLists;
2685 ParData parData;
2686 RecT r;
2687
2688 if (d != NULL && /* numItems <= 32767 && */ numItems > 0) {
2689 GetPanelExtra ((PaneL) d, &ddata);
2690 if (ddata.master == NULL) {
2691 ddata.master = (MasterPtr) MemNew (sizeof (MasterData));
2692 SetPanelExtra ((PaneL) d, &ddata);
2693 }
2694 numLists = (numItems / LISTSIZE) + 1;
2695 ObjectRect (d, &r);
2696 InsetRect (&r, 4, 4);
2697 if (numLists <= MAXLISTS && ddata.master != NULL) {
2698 masterPtr = ddata.master;
2699 for (list = 0; list < numLists; list++) {
2700 listPtr = masterPtr->list [list];
2701 if (listPtr == NULL) {
2702 masterPtr->list [list] = (ListDPtr) MemNew(sizeof(ListData));
2703 listPtr = masterPtr->list [list];
2704 }
2705 }
2706 if (colFmt == NULL) {
2707 colFmt = ddata.defaultColFmt;
2708 }
2709 if (colFmt == NULL) {
2710 defaultTable.pixWidth = r.right - r.left;
2711 defaultTable.charWidth = 80;
2712 colFmt = &defaultTable;
2713 }
2714 i = 0;
2715 while (! colFmt [i].last) {
2716 i++;
2717 }
2718 i++;
2719 numCols = i;
2720 colXPtr = CacheColFmt (d, colFmt);
2721 if (parFmt == NULL) {
2722 parFmt = ddata.defaultParFmt;
2723 }
2724 if (parFmt != NULL) {
2725 parData.openSpace = parFmt->openSpace;
2726 parData.keepWithNext = parFmt->keepWithNext;
2727 parData.keepTogether = parFmt->keepTogether;
2728 parData.newPage = parFmt->newPage;
2729 parData.tabStops = parFmt->tabStops;
2730 parData.minLines = MAX (parFmt->minLines, (Int2) 1);
2731 parData.minHeight = parFmt->minHeight;
2732 } else {
2733 parData.openSpace = TRUE;
2734 parData.keepWithNext = FALSE;
2735 parData.keepTogether = FALSE;
2736 parData.newPage = FALSE;
2737 parData.tabStops = FALSE;
2738 parData.minLines = 0;
2739 parData.minHeight = 0;
2740 }
2741 if (font == NULL) {
2742 font = ddata.defaultFont;
2743 }
2744 for (item = 0; item < numItems; item++) {
2745 list = (item / LISTSIZE);
2746 listPtr = masterPtr->list [list];
2747 if (listPtr != NULL) {
2748 index = (item % LISTSIZE);
2749 itemPtr = &(listPtr->items [index]);
2750 if (itemPtr != NULL) {
2751 itemPtr->prtProc = proc;
2752 itemPtr->dataPtr = NULL;
2753 itemPtr->text = NULL;
2754 itemPtr->cached = NULL;
2755 itemPtr->font = font;
2756 itemPtr->numRows = MAX (estLines, 1);
2757 itemPtr->numCols = numCols;
2758 itemPtr->colFmt = colXPtr;
2759 itemPtr->extra = NULL;
2760 itemPtr->startsAt = 0;
2761 itemPtr->openSpace = parData.openSpace;
2762 itemPtr->keepWithNext = parData.keepWithNext;
2763 itemPtr->keepTogether = parData.keepTogether;
2764 itemPtr->newPage = parData.newPage;
2765 itemPtr->tabStops = parData.tabStops;
2766 itemPtr->minLines = parData.minLines;
2767 itemPtr->minHeight = parData.minHeight;
2768 itemPtr->docOwnsData = FALSE;
2769 itemPtr->notCached = TRUE;
2770 itemPtr->neverCached = TRUE;
2771 if (item == 0) {
2772 UpdateItemHeights (itemPtr);
2773 lineHeight = itemPtr->lineHeight;
2774 leadHeight = itemPtr->leadHeight;
2775 }
2776 itemPtr->lineHeight = lineHeight;
2777 itemPtr->leadHeight = leadHeight;
2778 }
2779 }
2780 }
2781 ddata.numItems = numItems;
2782 ddata.numLines = UpdateLineStarts (&ddata, 0);
2783 SetPanelExtra ((PaneL) d, &ddata);
2784 if (ddata.upd != NULL) {
2785 ddata.upd ((DoC) d, 0, 0);
2786 }
2787 if (ddata.autoAdjust) {
2788 AdjustDocScroll (d);
2789 }
2790 }
2791 }
2792 }
2793
2794 /*****************************************************************************
2795 *
2796 * StdCache functions
2797 * Simple binary tree cache
2798 *
2799 *****************************************************************************/
2800
2801 extern void StdPutDocCache (DoC d, Int2 item, CharPtr text)
2802
2803 {
2804 DocData ddata;
2805 ItemPtr itemPtr;
2806
2807 if (d != NULL && item > 0) {
2808 GetPanelExtra ((PaneL) d, &ddata);
2809 itemPtr = GetItemPtr (&ddata, item - 1);
2810 if (itemPtr != NULL) {
2811 itemPtr->cached = MemFree (itemPtr->cached);
2812 itemPtr->cached = StringSave (text);
2813 }
2814 }
2815 }
2816
2817 extern CharPtr StdGetDocCache (DoC d, Int2 item)
2818
2819 {
2820 DocData ddata;
2821 ItemPtr itemPtr;
2822 CharPtr text = NULL;
2823
2824 if (d != NULL && item > 0) {
2825 GetPanelExtra ((PaneL) d, &ddata);
2826 itemPtr = GetItemPtr (&ddata, item - 1);
2827 if (itemPtr != NULL) {
2828 text = StringSave (itemPtr->cached);
2829 }
2830 }
2831 return text;
2832 }
2833
2834 extern void StdResetDocCache (DoC d, Int2 from, Int2 to)
2835
2836 {
2837 DocData ddata;
2838 Int2 i;
2839 ItemPtr itemPtr;
2840
2841 GetPanelExtra ((PaneL) d, &ddata);
2842 for (i = 0; i < ddata.numItems; i++) {
2843 itemPtr = GetItemPtr (&ddata, i);
2844 if (itemPtr != NULL) {
2845 itemPtr->cached = MemFree (itemPtr->cached);
2846 }
2847 }
2848 SetPanelExtra ((PaneL) d, &ddata);
2849 }
2850
2851 /*****************************************************************************
2852 *
2853 * ResetDocument (d)
2854 * Performs garbage collection on document data
2855 *
2856 *****************************************************************************/
2857
2858 static void ResetDocument (PaneL d)
2859
2860 {
2861 DocData ddata;
2862 Int2 i;
2863 ItemPtr itemPtr;
2864 MasterPtr masterPtr;
2865 RecT r;
2866
2867 GetPanelExtra (d, &ddata);
2868 if (ddata.data != NULL && ddata.cleanup != NULL) {
2869 ddata.cleanup ((DoC) d, ddata.data);
2870 }
2871 if (ddata.upd != NULL) {
2872 ddata.upd ((DoC) d, 0, 0);
2873 }
2874 ObjectRect (d, &r);
2875 InsetRect (&r, 4, 4);
2876 for (i = 0; i < ddata.numItems; i++) {
2877 itemPtr = GetItemPtr (&ddata, i);
2878 if (itemPtr != NULL) {
2879 itemPtr->text = (CharPtr) MemFree (itemPtr->text);
2880 if (itemPtr->docOwnsData) {
2881 itemPtr->dataPtr = (Pointer) MemFree (itemPtr->dataPtr);
2882 } else {
2883 itemPtr->dataPtr = NULL;
2884 }
2885 itemPtr->extra = MemFree (itemPtr->extra);
2886 itemPtr->cached = MemFree (itemPtr->cached);
2887 }
2888 }
2889 if (ddata.master != NULL) {
2890 masterPtr = ddata.master;
2891 for (i = 0; i < MAXLISTS; i++) {
2892 masterPtr->list [i] = (ListDPtr) MemFree(masterPtr->list [i]);
2893 }
2894 }
2895 ddata.colFmts = ValNodeFreeData (ddata.colFmts);
2896 ddata.numItems = 0;
2897 ddata.numLines = 0;
2898 ddata.barmax = 0;
2899 ddata.pgUp = 0;
2900 ddata.pgDn = 0;
2901 ddata.master = (MasterPtr) MemFree (ddata.master);
2902 for (i = 0; i < MAXFONTS; i++) {
2903 fontHeights [i].font = NULL;
2904 fontHeights [i].height = 0;
2905 }
2906 ddata.data = NULL;
2907 ddata.cleanup = NULL;
2908 ddata.firstHighlightItem = 0;
2909 ddata.lastHighlightItem = 0;
2910 SetPanelExtra ((PaneL) d, &ddata);
2911 }
2912
2913 /*****************************************************************************
2914 *
2915 * NewDocument (d)
2916 * Initialized document panel extra data
2917 *
2918 *****************************************************************************/
2919
2920 static void NewDocument (DoC d)
2921
2922 {
2923 DocData ddata;
2924 Int2 i;
2925
2926 ddata.numItems = 0;
2927 ddata.numLines = 0;
2928 ddata.barmax = 0;
2929 ddata.pgUp = 0;
2930 ddata.pgDn = 0;
2931 ddata.tabCount = 4;
2932 ddata.autoAdjust = TRUE;
2933 ddata.doc = d;
2934 ddata.master = NULL;
2935 ddata.draw = NULL;
2936 ddata.drawcell = NULL;
2937 ddata.pan = NULL;
2938 ddata.gray = NULL;
2939 ddata.invert = NULL;
2940 ddata.color = NULL;
2941 ddata.put = NULL;
2942 ddata.get = NULL;
2943 ddata.upd = NULL;
2944 ddata.data = NULL;
2945 ddata.cleanup = NULL;
2946 ddata.colFmts = NULL;
2947 for (i = 0; i < MAXFONTS; i++) {
2948 fontHeights [i].font = NULL;
2949 fontHeights [i].height = 0;
2950 }
2951 ddata.defaultParFmt = NULL;
2952 ddata.defaultColFmt = NULL;
2953 ddata.defaultFont = NULL;
2954 ddata.firstHighlightItem = 0;
2955 ddata.lastHighlightItem = 0;
2956 ddata.useRowsNotItems = FALSE;
2957 ddata.notify = NULL;
2958 SetPanelExtra ((PaneL) d, &ddata);
2959 }
2960
2961 /*****************************************************************************
2962 *
2963 * DocumentPanel (prnt, pixwidth, pixheight)
2964 * Creates an empty document object
2965 *
2966 *****************************************************************************/
2967
2968 extern DoC DocumentPanel (GrouP prnt, Int2 pixwidth, Int2 pixheight)
2969
2970 {
2971 DoC d;
2972 WindoW tempPort;
2973
2974 d = NULL;
2975 if (prnt != NULL) {
2976 tempPort = SavePort (prnt);
2977 d = (DoC) AutonomousPanel4 (prnt, pixwidth, pixheight, DrawDocument,
2978 DocumentScrlProc, NULL, sizeof (DocData),
2979 ResetDocument, NULL);
2980 if (d != NULL) {
2981 NewDocument (d);
2982 }
2983 RestorePort (tempPort);
2984 }
2985 return d;
2986 }
2987
2988 /*****************************************************************************
2989 *
2990 * SetDocProcs (d, click, drag, release, pan)
2991 * Sets mouse callbacks for a document object
2992 *
2993 *****************************************************************************/
2994
2995 extern void SetDocProcs (DoC d, DocClckProc click, DocClckProc drag,
2996 DocClckProc release, DocPanProc pan)
2997
2998 {
2999 DocData ddata;
3000
3001 if (d != NULL) {
3002 Nlm_SetPanelClick ((PaneL) d, (PnlClckProc) click, (PnlClckProc) drag,
3003 NULL, (PnlClckProc) release);
3004 GetPanelExtra ((PaneL) d, &ddata);
3005 ddata.pan = pan;
3006 SetPanelExtra ((PaneL) d, &ddata);
3007 }
3008 }
3009
3010 /*****************************************************************************
3011 *
3012 * SetDocShade (d, draw, gray, invert, color)
3013 * Sets draw callbacks for a document object
3014 *
3015 *****************************************************************************/
3016
3017 extern void SetDocShade (DoC d, DocDrawProc draw, DocShadeProc gray,
3018 DocShadeProc invert, DocShadeProc color)
3019
3020 {
3021 DocData ddata;
3022
3023 if (d != NULL) {
3024 GetPanelExtra ((PaneL) d, &ddata);
3025 ddata.draw = draw;
3026 ddata.gray = gray;
3027 ddata.invert = invert;
3028 ddata.color = color;
3029 SetPanelExtra ((PaneL) d, &ddata);
3030 }
3031 }
3032
3033 /*****************************************************************************
3034 *
3035 * SetDocExtra (d, drawcell)
3036 * Sets drawcell callback for a document object
3037 *
3038 *****************************************************************************/
3039
3040 extern void SetDocExtra (DoC d, DocCellProc drawcell)
3041
3042 {
3043 DocData ddata;
3044
3045 if (d != NULL) {
3046 GetPanelExtra ((PaneL) d, &ddata);
3047 ddata.drawcell = drawcell;
3048 SetPanelExtra ((PaneL) d, &ddata);
3049 }
3050 }
3051
3052 /*****************************************************************************
3053 *
3054 * SetDocCache (d, put, get, upd)
3055 * Sets cache callbacks for a document object
3056 *
3057 *****************************************************************************/
3058
3059 extern void SetDocCache (DoC d, DocPutProc put, DocGetProc get, DocUpdProc upd)
3060
3061 {
3062 DocData ddata;
3063
3064 if (d != NULL) {
3065 GetPanelExtra ((PaneL) d, &ddata);
3066 ddata.put = put;
3067 ddata.get = get;
3068 ddata.upd = upd;
3069 SetPanelExtra ((PaneL) d, &ddata);
3070 }
3071 }
3072
3073 /*****************************************************************************
3074 *
3075 * SetDocData (d, data, cleanup)
3076 * Attaches instance data to a document object
3077 *
3078 *****************************************************************************/
3079
3080 void SetDocData (DoC d, VoidPtr data, DocFreeProc cleanup)
3081
3082 {
3083 DocData ddata;
3084
3085 if (d != NULL) {
3086 GetPanelExtra ((PaneL) d, &ddata);
3087 ddata.data = data;
3088 ddata.cleanup = cleanup;
3089 SetPanelExtra ((PaneL) d, &ddata);
3090 }
3091 }
3092
3093 /*****************************************************************************
3094 *
3095 * GetDocData (d)
3096 * Returns the instance data attached to a document object
3097 *
3098 *****************************************************************************/
3099
3100 VoidPtr GetDocData (DoC d)
3101
3102 {
3103 DocData ddata;
3104
3105 if (d != NULL) {
3106 GetPanelExtra ((PaneL) d, &ddata);
3107 return (ddata.data);
3108 } else {
3109 return NULL;
3110 }
3111 }
3112
3113 /*****************************************************************************
3114 *
3115 * GetDocParams (d, numItems, numLines)
3116 * Returns document-specific information
3117 *
3118 *****************************************************************************/
3119
3120 void GetDocParams4 (DoC d, Int2Ptr numItems, Int4Ptr numLines)
3121
3122 {
3123 DocData ddata;
3124 Int2 items;
3125 Int4 lines;
3126
3127 items = 0;
3128 lines = 0;
3129 if (d != NULL) {
3130 GetPanelExtra ((PaneL) d, &ddata);
3131 items = ddata.numItems;
3132 lines = ddata.numLines;
3133 }
3134 if (numItems != NULL) {
3135 *numItems = items;
3136 }
3137 if (numLines != NULL) {
3138 *numLines = lines;
3139 }
3140 }
3141
3142 void GetDocParams (DoC d, Int2Ptr numItems, Int2Ptr numLines)
3143
3144 {
3145 Int4 lines;
3146
3147 GetDocParams4 (d, numItems, &lines);
3148 if (numLines != NULL) {
3149 *numLines = (Int2) lines;
3150 }
3151 }
3152
3153 /*****************************************************************************
3154 *
3155 * GetItemParams (d, item, startsAt, numRows, numCols, lineHeight, data)
3156 * Returns item-specific information
3157 *
3158 *****************************************************************************/
3159
3160 void GetItemParams4 (DoC d, Int2 item, Int4Ptr startsAt, Int2Ptr numRows,
3161 Int2Ptr numCols, Int2Ptr lineHeight, Pointer PNTR data)
3162
3163 {
3164 Int2 cols;
3165 Int4 first;
3166 VoidPtr dataPtr;
3167 DocData ddata;
3168 Int2 height;
3169 ItemPtr itemPtr;
3170 Int2 rows;
3171
3172 cols = 0;
3173 first = 0;
3174 height = 0;
3175 rows = 0;
3176 dataPtr = NULL;
3177 if (d != NULL && item > 0) {
3178 GetPanelExtra ((PaneL) d, &ddata);
3179 itemPtr = GetItemPtr (&ddata, item - 1);
3180 if (itemPtr != NULL) {
3181 first = itemPtr->startsAt;
3182 rows = itemPtr->numRows;
3183 cols = itemPtr->numCols;
3184 height = itemPtr->lineHeight;
3185 dataPtr = itemPtr->dataPtr;
3186 }
3187 }
3188 if (startsAt != NULL) {
3189 *startsAt = first;
3190 }
3191 if (numRows != NULL) {
3192 *numRows = rows;
3193 }
3194 if (numCols != NULL) {
3195 *numCols = cols;
3196 }
3197 if (lineHeight != NULL) {
3198 *lineHeight = height;
3199 }
3200 if (data != NULL) {
3201 *data = dataPtr;
3202 }
3203 }
3204
3205 void GetItemParams (DoC d, Int2 item, Int2Ptr startsAt, Int2Ptr numRows,
3206 Int2Ptr numCols, Int2Ptr lineHeight, Pointer PNTR data)
3207
3208 {
3209 Int4 first;
3210
3211 GetItemParams4 (d, item, &first, numRows, numCols, lineHeight, data);
3212 if (startsAt != NULL) {
3213 *startsAt = (Int2) first;
3214 }
3215 }
3216
3217 /*****************************************************************************
3218 *
3219 * GetColParams (d, item, col, pixPos, pixWidth, pixInset, just)
3220 * Returns column-specific information
3221 *
3222 *****************************************************************************/
3223
3224 void GetColParams (DoC d, Int2 item, Int2 col, Int2Ptr pixPos,
3225 Int2Ptr pixWidth, Int2Ptr pixInset, CharPtr just)
3226
3227 {
3228 ColXPtr colFmt;
3229 DocData ddata;
3230 Int2 inset;
3231 ItemPtr itemPtr;
3232 Char jst;
3233 Int2 position;
3234 RecT r;
3235 Int2 width;
3236
3237 inset = 0;
3238 position = 0;
3239 width = 0;
3240 jst = 'l';
3241 if (d != NULL && item > 0 && col > 0) {
3242 GetPanelExtra ((PaneL) d, &ddata);
3243 ObjectRect (d, &r);
3244 InsetRect (&r, 4, 4);
3245 itemPtr = GetItemPtr (&ddata, item - 1);
3246 if (itemPtr != NULL && col <itemPtr->numCols + 1) {
3247 colFmt = itemPtr->colFmt;
3248 if (colFmt != NULL) {
3249 SetTablePixFormat (colFmt, r.left, itemPtr->numCols);
3250 position = colFmt [col - 1].position;
3251 width = colFmt [col - 1].pixWidth;
3252 inset = colFmt [col - 1].pixInset;
3253 jst = justToChar [colFmt [col - 1].just];
3254 }
3255 }
3256 }
3257 if (pixPos != NULL) {
3258 *pixPos = position;
3259 }
3260 if (pixWidth != NULL) {
3261 *pixWidth = width;
3262 }
3263 if (pixInset != NULL) {
3264 *pixInset = inset;
3265 }
3266 if (just != NULL) {
3267 *just = jst;
3268 }
3269 }
3270
3271 /*****************************************************************************
3272 *
3273 * MapDocPoint (d, pt, item, row, col, rct)
3274 * Converts a mouse point to a item, row, and column positions
3275 * within a document
3276 *
3277 *****************************************************************************/
3278
3279 extern void MapDocPointEx (DoC d, PoinT pt, Int2Ptr item, Int2Ptr row, Int2Ptr col, RectPtr rct, Boolean prefer_first_match_col)
3280
3281 {
3282 Int2 cl;
3283 ColXPtr colFmt;
3284 DocData ddata;
3285 Int2 firstItem;
3286 Int2 firstLine;
3287 Boolean goOn, found;
3288 Int2 i;
3289 Int2 itemNum;
3290 ItemPtr itemPtr;
3291 Int2 itm;
3292 Int2 leadHeight;
3293 Int2 lineHeight;
3294 Int2 numCols;
3295 Int2 numRows;
3296 Int4 off;
3297 RecT q;
3298 RecT r;
3299 RecT rc;
3300 Int2 rw;
3301 BaR sb;
3302
3303 itm = 0;
3304 rw = 0;
3305 cl = 0;
3306 LoadRect (&rc, 0, 0, 0, 0);
3307 if (d != NULL) {
3308 GetPanelExtra ((PaneL) d, &ddata);
3309 ObjectRect (d, &r);
3310 InsetRect (&r, 4, 4);
3311 if (PtInRect (pt, &r)) {
3312 sb = GetSlateVScrollBar ((SlatE) d);
3313 if (sb != NULL) {
3314 goOn = TRUE;
3315 LoadRect (&q, r.left, r.top, r.right, r.top);
3316 off = GetBarValue (sb);
3317 itemNum = GetItemNum (&ddata, off);
3318 itemPtr = GetItemPtr (&ddata, itemNum);
3319 if (itemPtr != NULL) {
3320 firstLine = (Int2) (off - itemPtr->startsAt);
3321 firstItem = itemNum;
3322 while (goOn && itemNum < ddata.numItems) {
3323 itemPtr = GetItemPtr (&ddata, itemNum);
3324 if (itemPtr != NULL) {
3325 CacheIfNever (&ddata, itemNum + 1, itemPtr, &r, ddata.tabCount);
3326 SetTablePixFormat (itemPtr->colFmt, r.left, itemPtr->numCols);
3327 if (itemNum > firstItem) {
3328 leadHeight = itemPtr->leadHeight;
3329 } else {
3330 leadHeight = 0;
3331 }
3332 lineHeight = itemPtr->lineHeight;
3333 numRows = MIN (itemPtr->numRows - firstLine,
3334 MAX ((r.bottom - q.top - leadHeight) / lineHeight, 0));
3335 numCols = itemPtr->numCols;
3336 colFmt = itemPtr->colFmt;
3337 q.bottom = q.top + leadHeight + lineHeight * numRows;
3338 if (PtInRect (pt, &q) && numRows > 0) {
3339 goOn = FALSE;
3340 itm = itemNum + 1;
3341 if (pt.y <= q.top + leadHeight) {
3342 rw = 0;
3343 } else {
3344 rw = firstLine + ((pt.y - q.top - leadHeight) / lineHeight) + 1;
3345 }
3346 if (numCols > 0 && colFmt != NULL) {
3347 found = FALSE;
3348 for (i = 0; i < numCols && !found; i++) {
3349 if (pt.x >= colFmt [i].position &&
3350 pt.x < colFmt [i].position + colFmt [i].pixWidth) {
3351 cl = i + 1;
3352 if (rw > 0) {
3353 rc.left = colFmt [i].position;
3354 rc.top = q.top + leadHeight + lineHeight * (rw - firstLine - 1);
3355 rc.right = rc.left + colFmt [i].pixWidth;
3356 rc.bottom = rc.top + lineHeight;
3357 }
3358 if (prefer_first_match_col) {
3359 found = TRUE;
3360 }
3361 }
3362 }
3363 }
3364 } else {
3365 q.top = q.bottom;
3366 }
3367 if (numRows < itemPtr->numRows - firstLine) {
3368 goOn = FALSE;
3369 }
3370 }
3371 itemNum++;
3372 firstLine = 0;
3373 }
3374 }
3375 }
3376 }
3377 }
3378 if (item != NULL) {
3379 *item = itm;
3380 }
3381 if (row != NULL) {
3382 *row = rw;
3383 }
3384 if (col != NULL) {
3385 *col = cl;
3386 }
3387 if (rct != NULL) {
3388 *rct = rc;
3389 }
3390 }
3391
3392 extern void MapDocPoint (DoC d, PoinT pt, Int2Ptr item, Int2Ptr row, Int2Ptr col, RectPtr rct)
3393 {
3394 MapDocPointEx (d, pt, item, row, col, rct, FALSE);
3395 }
3396
3397 /*****************************************************************************
3398 *
3399 * GetDocText (d, item, row, col)
3400 * Returns a string with text from a document. If item, row, or col
3401 * parameters are 0, text is taken from any item, row, or column,
3402 * respectively. The string must be freed by the application
3403 *
3404 *****************************************************************************/
3405
3406 extern CharPtr GetDocText (DoC d, Int2 item, Int2 row, Int2 col)
3407
3408 {
3409 ByteStorePtr bsp;
3410 Char ch;
3411 Int2 cl;
3412 DocData ddata;
3413 Int2 i;
3414 ItemData itemData;
3415 ItemPtr itemPtr;
3416 Int2 k;
3417 Int2 num;
3418 CharPtr ptr;
3419 RecT r;
3420 Int2 rw;
3421 Int2 start;
3422 Int2 stop;
3423 CharPtr text;
3424
3425 text = NULL;
3426 if (d != NULL && item >= 0 && row >= 0 && col >= 0) {
3427 ObjectRect (d, &r);
3428 InsetRect (&r, 4, 4);
3429 GetPanelExtra ((PaneL) d, &ddata);
3430 if (ddata.numItems > 0) {
3431 bsp = BSNew (0);
3432 if (bsp != NULL) {
3433 if (item == 0) {
3434 start = 0;
3435 stop = ddata.numItems;
3436 } else if (item <= ddata.numItems) {
3437 start = item - 1;
3438 stop = item;
3439 } else {
3440 start = 0;
3441 stop = 0;
3442 }
3443 for (i = start; i < stop; i++) {
3444 itemPtr = GetItemPtr (&ddata, i);
3445 if (itemPtr != NULL) {
3446 itemData.text = NULL;
3447 itemData.prtProc = itemPtr->prtProc;
3448 itemData.dataPtr = itemPtr->dataPtr;
3449 itemData.font = itemPtr->font;
3450 itemData.extra = itemPtr->extra;
3451 itemData.openSpace = itemPtr->openSpace;
3452 itemData.tabStops = itemPtr->tabStops;
3453 itemData.numRows = itemPtr->numRows;
3454 itemData.numCols = itemPtr->numCols;
3455 itemData.minLines = itemPtr->minLines;
3456 itemData.minHeight = itemPtr->minHeight;
3457 itemData.colFmt = itemPtr->colFmt;
3458 SetTablePixFormat (itemData.colFmt, r.left, itemData.numCols);
3459 if (itemData.prtProc != NULL) {
3460 FormatText (&ddata, i + 1, &itemData, TRUE, ddata.tabCount);
3461 itemPtr->numRows = itemData.numRows;
3462 itemPtr->neverCached = itemData.neverCached;
3463 SetTablePixFormat (itemData.colFmt, r.left, itemData.numCols);
3464 text = itemData.text;
3465 if (text != NULL && *text != '\0' && itemData.colFmt != NULL) {
3466 if (i > start && itemData.openSpace > 0 && item == 0) {
3467 BSPutByte (bsp, (Int2) '\n');
3468 }
3469 rw = 0;
3470 cl = 0;
3471 ptr = text;
3472 ch = *ptr;
3473 while (ch != '\0') {
3474 if (ch == '\n') {
3475 if ((rw + 1 == row && col == 0) || row == 0) {
3476 BSPutByte (bsp, (Int2) '\n');
3477 }
3478 cl = 0;
3479 rw++;
3480 ptr++;
3481 } else if (ch == '\t') {
3482 if ((rw + 1 == row || row == 0) && col == 0) {
3483 BSPutByte (bsp, (Int2) '\t');
3484 }
3485 cl++;
3486 ptr++;
3487 } else {
3488 num = 0;
3489 while (ch != '\0' && ch != '\t' && ch != '\n') {
3490 num++;
3491 ch = ptr [num];
3492 }
3493 if (num > 0 && (cl +1 == col || col == 0) &&
3494 (rw + 1 == row || row == 0)) {
3495 for (k = 0; k < num; k++) {
3496 BSPutByte (bsp, (Int2) ptr [k]);
3497 }
3498 }
3499 ptr += num;
3500 }
3501 ch = *ptr;
3502 }
3503 }
3504 }
3505 MemFree (itemData.text);
3506 }
3507 }
3508 text = (CharPtr) BSMerge(bsp, NULL);
3509 BSFree (bsp);
3510 ddata.numLines = UpdateLineStarts (&ddata, start);
3511 SetPanelExtra ((PaneL) d, &ddata);
3512 }
3513 }
3514 }
3515 return text;
3516 }
3517
3518 /*****************************************************************************
3519 *
3520 * ItemIsVisible (d, item, top, bottom, firstLine)
3521 * Finds the visible region of an item in a document
3522 *
3523 *****************************************************************************/
3524
3525 extern Boolean ItemIsVisible (DoC d, Int2 item, Int2Ptr top,
3526 Int2Ptr bottom, Int2Ptr firstLine)
3527
3528 {
3529 DocData ddata;
3530 Int2 firstItem;
3531 Int2 fstLine;
3532 Boolean goOn;
3533 Int2 itemNum;
3534 ItemPtr itemPtr;
3535 Int2 leadHeight;
3536 Int2 lineHeight;
3537 Int2 numRows;
3538 Int4 off;
3539 RecT r;
3540 RecT rct;
3541 Boolean rsult;
3542 BaR sb;
3543
3544 rsult = FALSE;
3545 if (top != NULL) {
3546 *top = 0;
3547 }
3548 if (bottom != NULL) {
3549 *bottom = 0;
3550 }
3551 if (firstLine != NULL) {
3552 *firstLine = 0;
3553 }
3554 if (d != NULL) {
3555 ObjectRect (d, &r);
3556 InsetRect (&r, 4, 4);
3557 GetPanelExtra ((PaneL) d, &ddata);
3558 sb = GetSlateVScrollBar ((SlatE) d);
3559 if (item > 0 && item <= ddata.numItems && sb != NULL) {
3560 item--;
3561 goOn = TRUE;
3562 LoadRect (&rct, r.left, r.top, r.right, r.top);
3563 off = GetBarValue (sb);
3564 itemNum = GetItemNum (&ddata, off);
3565 itemPtr = GetItemPtr (&ddata, itemNum);
3566 if (itemPtr != NULL) {
3567 fstLine = (Int2) (off - itemPtr->startsAt);
3568 firstItem = itemNum;
3569 lineHeight = 0;
3570 leadHeight = 0;
3571 numRows = 0;
3572 while (goOn && itemNum < ddata.numItems && itemNum <= item) {
3573 itemPtr = GetItemPtr (&ddata, itemNum);
3574 if (itemPtr != NULL) {
3575 CacheIfNever (&ddata, itemNum + 1, itemPtr, &r, ddata.tabCount);
3576 SetTablePixFormat (itemPtr->colFmt, r.left, itemPtr->numCols);
3577 if (itemNum > firstItem) {
3578 leadHeight = itemPtr->leadHeight;
3579 } else {
3580 leadHeight = 0;
3581 }
3582 lineHeight = itemPtr->lineHeight;
3583 rct.top += leadHeight;
3584 numRows = MIN (itemPtr->numRows - fstLine,
3585 MAX ((r.bottom - rct.top) / lineHeight, 0));
3586 rct.bottom = rct.top + lineHeight * numRows;
3587 if (itemNum == item) {
3588 goOn = FALSE;
3589 if (numRows > 0) {
3590 if (top != NULL) {
3591 *top = rct.top;
3592 }
3593 if (bottom != NULL) {
3594 *bottom = rct.bottom;
3595 }
3596 if (firstLine != NULL) {
3597 *firstLine = fstLine;
3598 }
3599 rsult = TRUE;
3600 }
3601 } else {
3602 rct.top = rct.bottom;
3603 }
3604 if (numRows < itemPtr->numRows - fstLine) {
3605 goOn = FALSE;
3606 }
3607 }
3608 itemNum++;
3609 fstLine = 0;
3610 }
3611 }
3612 }
3613 }
3614 return rsult;
3615 }
3616
3617 /*****************************************************************************
3618 *
3619 * GetScrlParams (d, offset, firstShown, firstLine)
3620 * Returns scroll-specific information
3621 *
3622 *****************************************************************************/
3623
3624 extern Boolean GetScrlParams4 (DoC d, Int4Ptr offset,
3625 Int2Ptr firstShown, Int2Ptr firstLine)
3626
3627 {
3628 DocData ddata;
3629 Int2 item;
3630 Int4 line;
3631 Int4 off;
3632 Boolean rsult;
3633 BaR sb;
3634
3635 rsult = FALSE;
3636 off = 0;
3637 item = 0;
3638 line = 0;
3639 if (d != NULL) {
3640 GetPanelExtra ((PaneL) d, &ddata);
3641 sb = GetSlateVScrollBar ((SlatE) d);
3642 if (sb != NULL) {
3643 off = GetBarValue (sb);
3644 item = GetItemNum (&ddata, off);
3645 line = off - GetStartsAt (&ddata, item);
3646 rsult = TRUE;
3647 }
3648 }
3649 if (offset != NULL) {
3650 *offset = off;
3651 }
3652 if (firstShown != NULL) {
3653 *firstShown = item + 1;
3654 }
3655 if (firstLine != NULL) {
3656 *firstLine = (Int2) line;
3657 }
3658 return rsult;
3659 }
3660
3661 extern void SetScrlParams4 (DoC d, Int4 offset)
3662
3663 {
3664 BaR sb;
3665
3666 if (d != NULL) {
3667 sb = GetSlateVScrollBar ((SlatE) d);
3668 if (sb != NULL) {
3669 SetBarValue (sb, offset);
3670 }
3671 }
3672 }
3673
3674
3675 extern Boolean GetScrlParams (DoC d, Int2Ptr offset,
3676 Int2Ptr firstShown, Int2Ptr firstLine)
3677
3678 {
3679 Int4 off;
3680 Boolean rsult;
3681
3682 rsult = GetScrlParams4 (d, &off, firstShown, firstLine);
3683 if (offset != NULL) {
3684 *offset = (Int2) off;
3685 }
3686 return rsult;
3687 }
3688
3689 /*****************************************************************************
3690 *
3691 * RowIsVisible (d, item, row, top, bottom)
3692 * Finds the visible region of a row in an item of a document
3693 *
3694 *****************************************************************************/
3695
3696 extern Boolean RowIsVisible (DoC d, Int2 item, Int2 row,
3697 Int2Ptr top, Int2Ptr bottom)
3698
3699 {
3700 Int2 bt;
3701 Int2 first;
3702 Int2 from;
3703 Int2 lineHeight;
3704 Int2 numRows;
3705 RecT r;
3706 Boolean rsult;
3707 Int2 tmp;
3708 Int2 to;
3709 Int2 tp;
3710
3711 rsult = FALSE;
3712 if (top != NULL) {
3713 *top = 0;
3714 }
3715 if (bottom != NULL) {
3716 *bottom = 0;
3717 }
3718 if (d != NULL && item > 0) {
3719 if (Enabled (d) && AllParentsEnabled (d) &&
3720 Visible (d) && AllParentsVisible (d)) {
3721 if (ItemIsVisible (d, item, &tp, &bt, &first)) {
3722 ObjectRect (d, &r);
3723 InsetRect (&r, 4, 4);
3724 GetItemParams (d, item, NULL, &numRows, NULL, &lineHeight, NULL);
3725 from = MIN (row, numRows);
3726 to = MIN (row, numRows);
3727 first++;
3728 if (from > to) {
3729 tmp = from;
3730 from = to;
3731 to = tmp;
3732 }
3733 if (to >= first) {
3734 while (from > first) {
3735 tp += lineHeight;
3736 first++;
3737 }
3738 bt = tp;
3739 while (to >= from) {
3740 bt += lineHeight;
3741 from++;
3742 }
3743 if (tp >= r.top && tp <= r.bottom &&
3744 bt >= r.top && bt <= r.bottom) {
3745 if (top != NULL) {
3746 *top = tp;
3747 }
3748 if (bottom != NULL) {
3749 *bottom = bt;
3750 }
3751 rsult = TRUE;
3752 }
3753 }
3754 }
3755 }
3756 }
3757 return rsult;
3758 }
3759
3760 /*****************************************************************************
3761 *
3762 * InvalDocRows (d, item, from, to)
3763 * Invalidates rows in a document
3764 *
3765 *****************************************************************************/
3766
3767 extern void InvalDocRows (DoC d, Int2 item, Int2 from, Int2 to)
3768
3769 {
3770 Int2 bottom;
3771 Int2 first;
3772 Int2 lineHeight;
3773 Int2 numRows;
3774 RecT r;
3775 WindoW tempPort;
3776 Int2 tmp;
3777 Int2 top;
3778
3779 if (d != NULL) {
3780 if (Enabled (d) && AllParentsEnabled (d) &&
3781 Visible (d) && AllParentsVisible (d)) {
3782 if (item > 0 && from >= 0 && to >= 0) {
3783 if (ItemIsVisible (d, item, &top, &bottom, &first)) {
3784 ObjectRect (d, &r);
3785 InsetRect (&r, 4, 4);
3786 GetItemParams (d, item, NULL, &numRows, NULL, &lineHeight, NULL);
3787 from = MIN (from, numRows);
3788 to = MIN (to, numRows);
3789 first++;
3790 if (from > to) {
3791 tmp = from;
3792 from = to;
3793 to = tmp;
3794 }
3795 if (to >= first) {
3796 while (from > first) {
3797 top += lineHeight;
3798 first++;
3799 }
3800 bottom = top;
3801 while (to >= from) {
3802 bottom += lineHeight;
3803 from++;
3804 }
3805 if (top >= r.top && top <= r.bottom &&
3806 bottom >= r.top && bottom <= r.bottom) {
3807 r.top = top;
3808 r.bottom = bottom;
3809 tempPort = SavePort (d);
3810 Select (d);
3811 InsetRect (&r, -1, -1);
3812 InvalRect (&r);
3813 RestorePort (tempPort);
3814 }
3815 }
3816 }
3817 } else if (item == 0) {
3818 tempPort = SavePort (d);
3819 Select (d);
3820 ObjectRect (d, &r);
3821 InsetRect (&r, 3, 3);
3822 InvalRect (&r);
3823 RestorePort (tempPort);
3824 }
3825 }
3826 }
3827 }
3828
3829 /*****************************************************************************
3830 *
3831 * InvalDocCols (d, item, from, to)
3832 * Invalidates columns in a document
3833 *
3834 *****************************************************************************/
3835
3836 extern void InvalDocCols (DoC d, Int2 item, Int2 from, Int2 to)
3837
3838 {
3839 Int2 bottom;
3840 ColXPtr colFmt;
3841 DocData ddata;
3842 ItemPtr itemPtr;
3843 Int2 numCols;
3844 RecT r;
3845 WindoW tempPort;
3846 Int2 tmp;
3847 Int2 top;
3848
3849 if (d != NULL) {
3850 if (Enabled (d) && AllParentsEnabled (d) &&
3851 Visible (d) && AllParentsVisible (d)) {
3852 if (item > 0 && from >= 0 && to >= 0) {
3853 if (ItemIsVisible (d, item, &top, &bottom, NULL)) {
3854 GetPanelExtra ((PaneL) d, &ddata);
3855 itemPtr = GetItemPtr (&ddata, item - 1);
3856 if (itemPtr == NULL) return;
3857 colFmt = itemPtr->colFmt;
3858 if (colFmt == NULL) return;
3859 ObjectRect (d, &r);
3860 InsetRect (&r, 4, 4);
3861 numCols = itemPtr->numCols;
3862 from = MIN (from, numCols);
3863 to = MIN (to, numCols);
3864 if (from > to) {
3865 tmp = from;
3866 from = to;
3867 to = tmp;
3868 }
3869 if (from > 0) {
3870 from--;
3871 }
3872 if (to > 0 && to <= numCols) {
3873 to--;
3874 }
3875 if (from >= 0 && from < numCols && to >= 0 && to < numCols) {
3876 r.left = colFmt [from].position;
3877 r.right = colFmt [to].position + colFmt [to].pixWidth;
3878 if (top >= r.top && top <= r.bottom &&
3879 bottom >= r.top && bottom <= r.bottom) {
3880 r.top = top;
3881 r.bottom = bottom;
3882 tempPort = SavePort (d);
3883 Select (d);
3884 InsetRect (&r, -1, -1);
3885 InvalRect (&r);
3886 RestorePort (tempPort);
3887 }
3888 }
3889 }
3890 } else if (item == 0) {
3891 tempPort = SavePort (d);
3892 Select (d);
3893 ObjectRect (d, &r);
3894 InsetRect (&r, 3, 3);
3895 InvalRect (&r);
3896 RestorePort (tempPort);
3897 }
3898 }
3899 }
3900 }
3901
3902 /*****************************************************************************
3903 *
3904 * InvalDocument (d)
3905 * Invalidates visible area of a document
3906 *
3907 *****************************************************************************/
3908
3909 extern void InvalDocument (DoC d)
3910
3911 {
3912 InvalDocRows (d, 0, 0, 0);
3913 }
3914
3915 /*****************************************************************************
3916 *
3917 * UpdateDocument (d, from, to)
3918 * Invalidates and updates items in a document
3919 *
3920 *****************************************************************************/
3921
3922 extern void UpdateDocument (DoC d, Int2 from, Int2 to)
3923
3924 {
3925 Int2 bottom;
3926 Boolean botvis;
3927 DocData ddata;
3928 Int2 item;
3929 ItemPtr itemPtr;
3930 Int2 last;
3931 Int4 line;
3932 Int4 off;
3933 RecT r;
3934 RecT s;
3935 BaR sb;
3936 Int2 start;
3937 Int2 stop;
3938 Int2 swap;
3939 WindoW tempPort;
3940 Int2 top;
3941 Boolean topvis;
3942 Int2 vis;
3943
3944 if (d != NULL && from >= 0 && to >= 0) {
3945 GetPanelExtra ((PaneL) d, &ddata);
3946 if (from == 0 || from > ddata.numItems) {
3947 start = 0;
3948 from = 0;
3949 } else {
3950 start = from - 1;
3951 }
3952 if (to == 0 || to > ddata.numItems) {
3953 stop = ddata.numItems;
3954 to = ddata.numItems;
3955 } else {
3956 stop = to;
3957 }
3958 for (item = start; item < stop; item++) {
3959 itemPtr = GetItemPtr (&ddata,item);
3960 if (itemPtr != NULL) {
3961 itemPtr->text = (CharPtr) MemFree (itemPtr->text);
3962 itemPtr->notCached = TRUE;
3963 itemPtr->neverCached = TRUE;
3964 itemPtr->cached = (CharPtr) MemFree (itemPtr->cached);
3965 }
3966 }
3967 if (ddata.upd != NULL) {
3968 ddata.upd (d, MIN (from, to), MAX (from, to));
3969 }
3970 if (Enabled (d) && AllParentsEnabled (d) &&
3971 Visible (d) && AllParentsVisible (d)) {
3972 tempPort = SavePort (d);
3973 ObjectRect (d, &r);
3974 InsetRect (&r, 4, 4);
3975 Select (d);
3976 if (from > to && from != 0 && to != ddata.numItems) {
3977 swap = from;
3978 from = to;
3979 to = swap;
3980 }
3981 topvis = FALSE;
3982 botvis = FALSE;
3983 if (from > 0 && from <= ddata.numItems) {
3984 topvis = ItemIsVisible (d, from, &top, NULL, NULL);
3985 if (topvis) {
3986 r.top = top;
3987 }
3988 } else {
3989 topvis = TRUE;
3990 }
3991 if (to > 0 && to <= ddata.numItems) {
3992 botvis = ItemIsVisible (d, to, NULL, &bottom, NULL);
3993 if (botvis) {
3994 r.bottom = bottom;
3995 }
3996 } else {
3997 botvis = TRUE;
3998 }
3999 if (topvis || botvis) {
4000 InsetRect (&r, -1, -1);
4001 InvalRect (&r);
4002 } else {
4003 ObjectRect (d, &s);
4004 InsetRect (&s, 4, 4);
4005 sb = GetSlateVScrollBar ((SlatE) d);
4006 off = GetBarValue (sb);
4007 item = GetItemNum (&ddata, off);
4008 line = (Int2) (off - GetStartsAt (&ddata, item));
4009 vis = VisLinesBelow (&ddata, &s, item, line, NULL, NULL);
4010 last = GetItemNum (&ddata, off + vis - 1);
4011 if (item >= stop || last < start) {
4012 } else {
4013 InsetRect (&r, -1, -1);
4014 InvalRect (&r);
4015 }
4016 }
4017 RestorePort (tempPort);
4018 }
4019 AdjustDocScroll (d);
4020 }
4021 }
4022
4023 /*****************************************************************************
4024 *
4025 * SaveTableItem (itemPtr, f, tabStops, tabCount)
4026 * Reformats and saves an item to a file
4027 *
4028 *****************************************************************************/
4029
4030 static void SaveTableItem (ItemPtr itemPtr, FILE *f,
4031 Boolean tabStops, Int2 tabCount)
4032
4033 {
4034 Char ch;
4035 Int2 col;
4036 ColXPtr colFmt;
4037 Int2 i;
4038 Int2 insetLeft;
4039 Int2 insetRight;
4040 Char just;
4041 Int2 next;
4042 Int2 num;
4043 Int2 pos;
4044 CharPtr ptr;
4045 Int2 row;
4046 CharPtr text;
4047
4048 if (itemPtr != NULL && f != NULL) {
4049 text = itemPtr->text;
4050 colFmt = itemPtr->colFmt;
4051 if (text != NULL && *text != '\0' && colFmt != NULL) {
4052 pos = 0;
4053 row = 0;
4054 col = 0;
4055 ptr = text;
4056 ch = *ptr;
4057 while (ch != '\0') {
4058 if (ch == '\n') {
4059 col = 0;
4060 row++;
4061 ptr++;
4062 pos = 0;
4063 fputc ('\n', f);
4064 } else if (ch == '\t' && (! tabStops)) {
4065 col++;
4066 ptr++;
4067 } else {
4068 num = 0;
4069 while (ch != '\0' && (ch != '\t' || tabStops) && ch != '\n') {
4070 num++;
4071 ch = ptr [num];
4072 }
4073 if (num > 0 && col < itemPtr->numCols) {
4074 just = justToChar [colFmt [col].just];
4075 if (just == 'c') {
4076 insetLeft = colFmt [col].charInset;
4077 insetRight = colFmt [col].charInset;
4078 } else if (just == 'l') {
4079 insetLeft = colFmt [col].charInset;
4080 insetRight = 0;
4081 } else if (just == 'r') {
4082 insetLeft = 0;
4083 insetRight = colFmt [col].charInset;
4084 } else {
4085 insetLeft = 0;
4086 insetRight = 0;
4087 }
4088 next = colFmt [col].position + insetLeft;
4089 if (tabCount > 0) {
4090 while (num > 0 && *ptr == '\t') {
4091 num--;
4092 ptr++;
4093 next += tabCount;
4094 }
4095 }
4096 while (pos < next) {
4097 fputc (' ', f);
4098 pos++;
4099 }
4100 if (just == 'r') {
4101 next = colFmt [col].position + colFmt [col].charWidth -
4102 insetRight - num;
4103 while (pos < next) {
4104 fputc (' ', f);
4105 pos++;
4106 }
4107 } else if (just == 'c') {
4108 next = colFmt [col].position + (colFmt [col].charWidth -
4109 insetRight - num) / 2;
4110 while (pos < next) {
4111 fputc (' ', f);
4112 pos++;
4113 }
4114 }
4115 for (i = 0; i < num; i++) {
4116 fputc (ptr [i], f);
4117 pos++;
4118 }
4119 }
4120 ptr += num;
4121 }
4122 ch = *ptr;
4123 }
4124 }
4125 }
4126 }
4127
4128 /*****************************************************************************
4129 *
4130 * SaveDocument (d, f)
4131 * Saves all document items to a file
4132 *
4133 *****************************************************************************/
4134
4135 extern void SaveDocument (DoC d, FILE *f)
4136
4137 {
4138 DocData ddata;
4139 Int2 i;
4140 ItemData itemData;
4141 ItemPtr itemPtr;
4142
4143 if (d != NULL && f != NULL) {
4144 GetPanelExtra ((PaneL) d, &ddata);
4145 ddata.put = NULL;
4146 ddata.get = NULL;
4147 ddata.upd = NULL;
4148 for (i = 0; i < ddata.numItems; i++) {
4149 itemPtr = GetItemPtr (&ddata, i);
4150 if (itemPtr != NULL) {
4151 itemData.text = NULL;
4152 itemData.cached = NULL;
4153 itemData.prtProc = itemPtr->prtProc;
4154 itemData.dataPtr = itemPtr->dataPtr;
4155 itemData.font = itemPtr->font;
4156 itemData.extra = itemPtr->extra;
4157 itemData.openSpace = itemPtr->openSpace;
4158 itemData.tabStops = itemPtr->tabStops;
4159 itemData.numRows = itemPtr->numRows;
4160 itemData.numCols = itemPtr->numCols;
4161 itemData.minLines = itemPtr->minLines;
4162 itemData.minHeight = itemPtr->minHeight;
4163 itemData.colFmt = itemPtr->colFmt;
4164 SetTableCharFormat (itemData.colFmt, itemData.numCols);
4165 if (itemData.prtProc != NULL) {
4166 FormatText (&ddata, i + 1, &itemData, FALSE, ddata.tabCount);
4167 SetTableCharFormat (itemData.colFmt, itemData.numCols);
4168 if (i > 0 && itemData.openSpace > 0) {
4169 fputc ('\n', f);
4170 }
4171 SaveTableItem (&itemData, f,
4172 (Boolean) (unsigned int) itemData.tabStops,
4173 ddata.tabCount);
4174 MemFree (itemData.text);
4175 }
4176 }
4177 }
4178 }
4179 }
4180
4181 /*****************************************************************************
4182 *
4183 * SaveDocumentItem (d, f, item)
4184 * Saves one document item to a file
4185 *
4186 *****************************************************************************/
4187
4188 extern void SaveDocumentItem (DoC d, FILE *f, Int2 item)
4189
4190 {
4191 DocData ddata;
4192 ItemData itemData;
4193 ItemPtr itemPtr;
4194
4195 if (d != NULL && f != NULL) {
4196 GetPanelExtra ((PaneL) d, &ddata);
4197 ddata.put = NULL;
4198 ddata.get = NULL;
4199 ddata.upd = NULL;
4200 if (item > 0 && item <= ddata.numItems) {
4201 itemPtr = GetItemPtr (&ddata, item - 1);
4202 if (itemPtr != NULL) {
4203 itemData.text = NULL;
4204 itemData.cached = NULL;
4205 itemData.prtProc = itemPtr->prtProc;
4206 itemData.dataPtr = itemPtr->dataPtr;
4207 itemData.font = itemPtr->font;
4208 itemData.extra = itemPtr->extra;
4209 itemData.openSpace = itemPtr->openSpace;
4210 itemData.tabStops = itemPtr->tabStops;
4211 itemData.numRows = itemPtr->numRows;
4212 itemData.numCols = itemPtr->numCols;
4213 itemData.minLines = itemPtr->minLines;
4214 itemData.minHeight = itemPtr->minHeight;
4215 itemData.colFmt = itemPtr->colFmt;
4216 SetTableCharFormat (itemData.colFmt, itemData.numCols);
4217 if (itemData.prtProc != NULL) {
4218 FormatText (&ddata, item, &itemData, FALSE, ddata.tabCount);
4219 SetTableCharFormat (itemData.colFmt, itemData.numCols);
4220 /*
4221 if (item > 1 && itemData.openSpace > 0) {
4222 fputc ('\n', f);
4223 }
4224 */
4225 SaveTableItem (&itemData, f,
4226 (Boolean) (unsigned int) itemData.tabStops,
4227 ddata.tabCount);
4228 MemFree (itemData.text);
4229 }
4230 }
4231 }
4232 }
4233 }
4234
4235 /*****************************************************************************
4236 *
4237 * PrintDocument (d)
4238 * Reformats and sends a document to the printer
4239 *
4240 *****************************************************************************/
4241
4242 #ifdef WIN_MOTIF
4243 extern CharPtr Nlm_XrmGetResource (const Char PNTR _resource);
4244 #endif
4245
4246 extern void PrintDocument (DoC d)
4247
4248 {
4249 #ifndef WIN_MOTIF
4250 DocData ddata;
4251 Boolean goOn;
4252 Int2 i;
4253 Int2 item;
4254 ItemPtr itemPtr;
4255 ItemData itemData;
4256 Int2 line;
4257 Boolean newPage;
4258 Int2 pixels;
4259 RecT r;
4260 RecT rct;
4261 FloatHi scale;
4262 Int2 visBelow;
4263 WindoW w;
4264
4265 if (d != NULL) {
4266 GetPanelExtra ((PaneL) d, &ddata);
4267 ddata.put = NULL;
4268 ddata.get = NULL;
4269 ddata.upd = NULL;
4270 if (ddata.numItems > 0) {
4271 ObjectRect (d, &rct);
4272 InsetRect (&rct, 4, 4);
4273 w = StartPrinting ();
4274 if (w != NULL) {
4275 for (i = 0; i < MAXFONTS; i++) {
4276 fontHeights [i].font = NULL;
4277 fontHeights [i].height = 0;
4278 }
4279 goOn = TRUE;
4280 pixels = 0;
4281 item = 0;
4282 newPage = TRUE;
4283 while (item < ddata.numItems && goOn) {
4284 if (newPage) {
4285 goOn = StartPage ();
4286 newPage = FALSE;
4287 PrintingRect (&r);
4288 }
4289 if (goOn) {
4290 itemPtr = GetItemPtr (&ddata, item);
4291 if (itemPtr != NULL) {
4292 itemData.text = NULL;
4293 itemData.cached = NULL;
4294 itemData.prtProc = itemPtr->prtProc;
4295 itemData.dataPtr = itemPtr->dataPtr;
4296 itemData.font = itemPtr->font;
4297 itemData.extra = itemPtr->extra;
4298 itemData.openSpace = itemPtr->openSpace;
4299 itemData.keepWithNext = itemPtr->keepWithNext;
4300 itemData.keepTogether = itemPtr->keepTogether;
4301 itemData.newPage = itemPtr->newPage;
4302 itemData.tabStops = itemPtr->tabStops;
4303 itemData.numRows = itemPtr->numRows;
4304 itemData.numCols = itemPtr->numCols;
4305 itemData.minLines = itemPtr->minLines;
4306 itemData.minHeight = itemPtr->minHeight;
4307 itemData.colFmt = (ColXPtr) MemNew (itemData.numCols * sizeof (ColXData));
4308 if (itemData.colFmt != NULL) {
4309 MemCopy (itemData.colFmt, itemPtr->colFmt,
4310 itemData.numCols * sizeof (ColXData));
4311 for (i = 0; i < itemData.numCols; i++) {
4312 if (itemData.colFmt [i].zeroWidth) {
4313 itemData.colFmt [i].pixWidth = 0;
4314 }
4315 }
4316 }
4317 UpdateItemHeights (&itemData);
4318 scale = (FloatHi) (r.right - r.left) / (FloatHi) (rct.right - rct.left);
4319 for (i = 0; i < itemData.numCols; i++) {
4320 itemData.colFmt [i].pixWidth = (Int2) (scale *
4321 (FloatHi) itemData.colFmt [i].pixWidth);
4322 }
4323 SetTablePixFormat (itemData.colFmt, r.left, itemData.numCols);
4324 if (itemData.prtProc != NULL) {
4325 FormatText (&ddata, item + 1, &itemData, TRUE, ddata.tabCount);
4326 SetTablePixFormat (itemData.colFmt, r.left, itemData.numCols);
4327 if (pixels != 0) {
4328 r.top += itemData.leadHeight;
4329 }
4330 visBelow = (r.bottom - r.top) / itemData.lineHeight;
4331 if ((itemData.keepTogether && visBelow < itemData.numRows) ||
4332 itemData.newPage) {
4333 goOn = EndPage ();
4334 if (goOn) {
4335 goOn = StartPage ();
4336 }
4337 newPage = FALSE;
4338 PrintingRect (&r);
4339 visBelow = (r.bottom - r.top) / itemData.lineHeight;
4340 }
4341 line = 0;
4342 while (visBelow + line < itemData.numRows && goOn) {
4343 pixels = DrawTableItem (d, &ddata, &itemData, &r, item, line, NULL,
4344 NULL, NULL, TRUE, ddata.tabCount);
4345 r.top += pixels;
4346 line += visBelow;
4347 goOn = EndPage ();
4348 if (goOn) {
4349 StartPage ();
4350 }
4351 newPage = FALSE;
4352 PrintingRect (&r);
4353 visBelow = (r.bottom - r.top) / itemData.lineHeight;
4354 }
4355 if (visBelow > 0 && goOn) {
4356 pixels = DrawTableItem (d, &ddata, &itemData, &r, item, line, NULL,
4357 NULL, NULL, TRUE, ddata.tabCount);
4358 r.top += pixels;
4359 }
4360 }
4361 MemFree (itemData.text);
4362 MemFree (itemData.colFmt);
4363 }
4364 }
4365 item++;
4366 if (r.top >= r.bottom) {
4367 goOn = EndPage ();
4368 newPage = TRUE;
4369 }
4370 }
4371 if ((! newPage) && goOn) {
4372 goOn = EndPage ();
4373 }
4374 EndPrinting (w);
4375 for (i = 0; i < MAXFONTS; i++) {
4376 fontHeights [i].font = NULL;
4377 fontHeights [i].height = 0;
4378 }
4379 }
4380 }
4381 }
4382 #endif
4383 #ifdef WIN_MOTIF
4384 Char cmmd [256];
4385 FILE *f;
4386 Int2 len;
4387 CharPtr printCmd;
4388 Char str [PATH_MAX];
4389
4390 if (d != NULL) {
4391 TmpNam (str);
4392 f = FileOpen (str, "w");
4393 if (f != NULL) {
4394 SaveDocument (d, f);
4395 FileClose (f);
4396 printCmd = Nlm_XrmGetResource ("printCommand");
4397 if (printCmd != NULL) {
4398 StringNCpy_0 (cmmd, printCmd, sizeof (cmmd) - 1);
4399 } else {
4400 StringCpy (cmmd, "lp -c");
4401 }
4402 MemFree (printCmd);
4403 len = (Int2) StringLen (cmmd);
4404 while (len > 0 && cmmd [len] == ' ') {
4405 cmmd [len] = '\0';
4406 len--;
4407 }
4408 StringCat (cmmd, " ");
4409 StringCat (cmmd, str);
4410 StringCat (cmmd, "; rm ");
4411 StringCat (cmmd, str);
4412 system (cmmd);
4413 } else {
4414 StringCpy (cmmd, "rm ");
4415 StringCat (cmmd, str);
4416 system (cmmd);
4417 }
4418 }
4419 #endif
4420 }
4421
4422 /*****************************************************************************
4423 *
4424 * displayTable
4425 * Default column table for file display functions
4426 *
4427 *****************************************************************************/
4428
4429 static ColData displayTable = {0, 0, 80, 0, NULL, 'l',
4430 TRUE, FALSE, FALSE, FALSE, TRUE};
4431
4432 /*****************************************************************************
4433 *
4434 * GetChar (fp)
4435 * Gets a single character from a file, returning '\0' on end of file
4436 *
4437 *****************************************************************************/
4438
4439 static Char GetChar (FILE *fp)
4440
4441 {
4442 #if (defined(OS_DOS) || defined (OS_NT))
4443 Int2 actual;
4444 Char buf [32];
4445 Char ch;
4446
4447 ch = '\0';
4448 actual = (Int2) FileRead (buf, 1, 1, fp);
4449 if (actual > 0) {
4450 ch = buf [0];
4451 }
4452 return ch;
4453 #else
4454 int ch;
4455
4456 ch = fgetc (fp);
4457 if (ch == EOF) {
4458 ch = '\0';
4459 }
4460 return (Char) ch;
4461 #endif
4462 }
4463
4464 /*****************************************************************************
4465 *
4466 * DisplayFancy (d, file, parFmt, colFmt, font, tabStops)
4467 * Uses a document to display a file, allowing paragraph and column
4468 * formatting to be specified
4469 *
4470 *****************************************************************************/
4471
4472 extern void DisplayFancy (DoC d, CharPtr file, ParPtr parFmt,
4473 ColPtr colFmt, FonT font, Int2 tabStops)
4474
4475 {
4476 Int2 actual;
4477 Char ch;
4478 Int2 cnt;
4479 Int8 cntr;
4480 DocData ddata;
4481 FILE *fp;
4482 Int2 leftOver;
4483 ParData para;
4484 RecT r;
4485 WindoW tempPort;
4486 CharPtr text;
4487 CharPtr txt;
4488 #ifdef WIN_MAC
4489 CharPtr p;
4490 CharPtr q;
4491 #endif
4492 #if (defined(OS_DOS) || defined (OS_NT))
4493 CharPtr p;
4494 CharPtr q;
4495 #endif
4496
4497 if (d != NULL && file != NULL && file [0] != '\0') {
4498 GetPanelExtra ((PaneL) d, &ddata);
4499 ddata.tabCount = tabStops;
4500 SetPanelExtra ((PaneL) d, &ddata);
4501 if (parFmt == NULL) {
4502 parFmt = ¶
4503 }
4504 if (colFmt == NULL) {
4505 colFmt = &displayTable;
4506 }
4507 Reset (d);
4508 tempPort = SavePort (d);
4509 ObjectRect (d, &r);
4510 InsetRect (&r, 4, 4);
4511 displayTable.pixWidth = r.right - r.left;
4512 if (font == NULL) {
4513 font = systemFont;
4514 }
4515 text = (CharPtr) MemNew (24000);
4516 if (text != NULL) {
4517 fp = FileOpen (file, "r");
4518 if (fp != NULL) {
4519 leftOver = 0;
4520 cntr = FileLength (file);
4521 cnt = (Int2) MIN (cntr, 15000L);
4522 para.openSpace = FALSE;
4523 para.keepWithNext = FALSE;
4524 para.keepTogether = FALSE;
4525 para.newPage = FALSE;
4526 para.tabStops = TRUE;
4527 para.minLines = 0;
4528 para.minHeight = 0;
4529 while (cnt > 0 && cntr > 0) {
4530 txt = text + leftOver;
4531 actual = (Int2) FileRead (txt, 1, cnt, fp);
4532 if (actual > 0) {
4533 cnt = actual;
4534 txt [cnt] = '\0';
4535 ch = GetChar (fp);
4536 while (ch != '\0' && ch != '\n' && cnt < 15900) {
4537 txt [cnt] = ch;
4538 cnt++;
4539 ch = GetChar (fp);
4540 }
4541 while ((ch == '\n' || ch == '\r') && cnt < 15900) {
4542 txt [cnt] = ch;
4543 cnt++;
4544 ch = GetChar (fp);
4545 }
4546 txt [cnt] = '\0';
4547 #if (defined(OS_DOS) || defined (OS_NT))
4548 p = text;
4549 q = text;
4550 while (*p) {
4551 if (*p == '\r') {
4552 p++;
4553 } else {
4554 *q = *p;
4555 p++;
4556 q++;
4557 }
4558 }
4559 *q = '\0';
4560 #endif
4561 #ifdef WIN_MAC
4562 p = text;
4563 q = text;
4564 while (*p) {
4565 if (*p == '\n') {
4566 *q = '\n';
4567 p++;
4568 q++;
4569 if (*p == '\r') {
4570 p++;
4571 }
4572 } else if (*p == '\r') {
4573 *q = '\n';
4574 p++;
4575 q++;
4576 if (*p == '\n') {
4577 p++;
4578 }
4579 } else {
4580 *q = *p;
4581 p++;
4582 q++;
4583 }
4584 }
4585 *q = '\0';
4586 #endif
4587 AppendText (d, text, parFmt, colFmt, font);
4588 leftOver = 1;
4589 text [0] = ch;
4590 cntr -= cnt;
4591 cnt = (Int2) MIN (cntr, 15000L);
4592 } else {
4593 cnt = 0;
4594 cntr = 0;
4595 }
4596 }
4597 FileClose (fp);
4598 }
4599 text = (CharPtr) MemFree (text);
4600 }
4601 if (Enabled (d) && AllParentsEnabled (d) &&
4602 Visible (d) && AllParentsVisible (d)) {
4603 ObjectRect (d, &r);
4604 InsetRect (&r, 3, 3);
4605 Select (d);
4606 InvalRect (&r);
4607 }
4608 if (! ddata.autoAdjust) {
4609 AdjustDocScroll (d);
4610 }
4611 RestorePort (tempPort);
4612 }
4613 }
4614
4615 /*****************************************************************************
4616 *
4617 * DisplayFile (d, file, font)
4618 * Simple function to display a file in a document
4619 *
4620 *****************************************************************************/
4621
4622 extern void DisplayFile (DoC d, CharPtr file, FonT font)
4623
4624 {
4625 DisplayFancy (d, file, NULL, NULL, font, 4);
4626 }
4627
4628 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |