"Fossies" - the Fresh Open Source Software Archive 
Member "jpilot-2_0_1/print.c" (3 Apr 2021, 40224 Bytes) of package /linux/privat/jpilot-2_0_1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "print.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
1.8.2_vs_2_0_1.
1 /*******************************************************************************
2 * print.c
3 * A module of J-Pilot http://jpilot.org
4 *
5 * Copyright (C) 2000-2014 by Judd Montgomery
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ******************************************************************************/
20
21 /********************************* Includes ***********************************/
22 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <time.h>
27 #include <ctype.h>
28
29 #include "print.h"
30 #include "print_headers.h"
31 #include "print_logo.h"
32 #include "datebook.h"
33 #include "calendar.h"
34 #include "address.h"
35 #include "todo.h"
36 #include "sync.h"
37 #include "prefs.h"
38 #include "log.h"
39 #include "i18n.h"
40 #ifdef HAVE_LOCALE_H
41 # include <locale.h>
42 #endif
43
44 /********************************* Constants **********************************/
45 #ifdef JPILOT_PRINTABLE
46 # define FLAG_CHAR 'A'
47 # define Q_FLAG_CHAR "A"
48 #else
49 # define FLAG_CHAR 010
50 # define Q_FLAG_CHAR "\\010"
51 #endif
52
53 /******************************* Global vars **********************************/
54 static FILE *out;
55 static int first_hour, first_min, last_hour, last_min;
56 extern int datebk_category;
57
58 static const char *PaperSizes[] = {
59 "Letter", "Legal", "Statement", "Tabloid", "Ledger", "Folio", "Quarto",
60 "7x9", "9x11", "9x12", "10x13", "10x14", "Executive",
61 "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7", "A8", "A9", "A10",
62 "B0", "B1", "B2", "B3", "B4", "B5", "B6", "B7", "B8", "B9", "B10",
63 "ISOB0", "ISOB1", "ISOB2", "ISOB3", "ISOB4", "ISOB5", "ISOB6", "ISOB7",
64 "ISOB8", "ISOB9", "ISOB10",
65 "C0", "C1", "C2", "C3", "C4", "C5", "C6", "C7", "DL", "Filo"
66 };
67
68 /****************************** Prototypes ************************************/
69 static int fill_in(struct tm *date, CalendarEventList *a_list);
70 static void ps_strncat(char *dest, const char *src, int n);
71
72 /****************************** Main Code *************************************/
73 static FILE *print_open(void)
74 {
75 const char *command;
76
77 get_pref(PREF_PRINT_COMMAND, NULL, &command);
78 if (command) {
79 return popen(command, "w");
80 } else {
81 return NULL;
82 }
83 }
84
85 static void print_close(FILE *f)
86 {
87 pclose(f);
88 }
89
90 static int courier_12(void)
91 {
92 /* fprintf(out, "/Courier 12 selectfont\n"); */
93 fprintf(out, "%cC12\n", FLAG_CHAR);
94 return EXIT_SUCCESS;
95 }
96
97 static int courier_bold_12(void)
98 {
99 /* fprintf(out, "/Courier-Bold 12 selectfont\n"); */
100 fprintf(out, "%cCB12\n", FLAG_CHAR);
101 return EXIT_SUCCESS;
102 }
103
104 static int clip_to_box(float x1, float y1, float x2, float y2)
105 {
106 fprintf(out, "%g inch %g inch %g inch %g inch rectclip\n",
107 x1, y1, x2-x1, y2-y1);
108 return EXIT_SUCCESS;
109 }
110
111 static int puttext(float x, float y, const char *text)
112 {
113 int len;
114 char *buf;
115
116 len = strlen(text);
117 buf = malloc(2 * len + 1);
118 memset(buf, 0, 2 * len + 1);
119 ps_strncat(buf, text, 2 * len);
120 fprintf(out, "%g inch %g inch moveto (%s) show\n", x, y, buf);
121 free(buf);
122 return EXIT_SUCCESS;
123 }
124
125 static int header(void)
126 {
127 time_t ltime;
128
129 time(<ime);
130 fprintf(out,
131 "%%!PS-Adobe-2.0\n"
132 "%%%%Creator: J-Pilot\n"
133 "%%%%CreationDate: %s"
134 "%%%%DocumentData: Clean7Bit\n"
135 "%%%%Orientation: Portrait\n"
136 "%%DocumentFonts: Times-Roman Times-Bold Courier Courier-Bold\n"
137 "%%%%Magnification: 1.0000\n"
138 "%%%%Pages: 1\n"
139 "%%%%EndComments\n"
140 "%%%%BeginProlog\n"
141 ,ctime(<ime));
142 fprintf(out, "/PageSize (%s) def\n\n", PaperSizes[PAPER_Letter]);
143 print_common_prolog(out);
144 fprintf(out,
145 "%%%%EndProlog\n"
146 "%%%%BeginSetup\n");
147 print_common_setup(out);
148 fprintf(out, "595 612 div 842 792 div Min dup scale %% HACK!!!! (CMB)\n");
149 /* This hack pre-scales to compensate for the standard scaling
150 mechanism below, to avoid me having to redo the layout of
151 the dayview for the A4 standard size page. */
152 fprintf(out,
153 "%%%%EndSetup\n"
154 "%%%%Page: 1 1\n\n");
155
156 return EXIT_SUCCESS;
157 }
158
159 static int print_dayview(struct tm *date, CalendarEventList *ce_list)
160 {
161 char str[80];
162 char datef[80];
163 time_t ltime;
164 struct tm *now;
165 const char *svalue;
166
167 #ifdef HAVE_LOCALE_H
168 char *current_locale;
169 current_locale = setlocale(LC_NUMERIC,"C");
170 #endif
171
172 header();
173 /* Draw the 2 gray columns and header block */
174 print_day_header(out);
175
176 /* Put the month name up */
177 fprintf(out, "/Times-Bold-ISOLatin1 findfont 20 scalefont setfont\n"
178 "newpath 0 setgray\n");
179 get_pref(PREF_LONGDATE, NULL, &svalue);
180 strftime(str, sizeof(str), _(svalue), date);
181 puttext(0.5, 10.25, str);
182
183 /* Put the weekday name up */
184 fprintf(out, "/Times-Roman-ISOLatin1 findfont 15 scalefont setfont\n");
185 strftime(str, sizeof(str), "%A", date);
186 puttext(0.5, 10, str);
187
188 /* Put the time of printing up */
189 fprintf(out, "newpath\n"
190 "/Times-Roman-ISOLatin1 findfont 10 scalefont setfont\n");
191
192 time(<ime);
193 now = localtime(<ime);
194 get_pref(PREF_SHORTDATE, NULL, &svalue);
195 g_snprintf(datef, sizeof(datef), "%s %s", "Printed on: ", svalue);
196 strftime(str, sizeof(str), datef, now);
197 puttext(0.5, 0.9, str);
198 puttext(7.5, 0.9, "J-Pilot");
199 fprintf(out, "stroke\n");
200
201 print_logo(out, 40, 90, 0.35);
202
203 /* Put the appointments on the dayview calendar */
204 fill_in(date, ce_list);
205
206 fprintf(out, "showpage\n");
207 fprintf(out, "%%%%EOF\n");
208
209 #ifdef HAVE_LOCALE_H
210 setlocale(LC_ALL, current_locale);
211 #endif
212
213 return EXIT_SUCCESS;
214 }
215
216 static int fill_in(struct tm *date, CalendarEventList *ce_list)
217 {
218 CalendarEventList *temp_cel;
219 int i;
220 int hours[24];
221 int defaults1=0, defaults2=0;
222 int hour24;
223 int am;
224 float top_y=9.40;
225 float default_y=3.40;
226 float indent1=1.25;
227 float indent2=5.00;
228 float step=0.12; /* This is the space between lines */
229 float x,y;
230 int max_per_line=4;
231 char str[256];
232 char datef[32];
233
234 for (i=0; i<24; i++) {
235 hours[i]=0;
236 }
237
238 /* We have to go through them twice, once for AM, and once for PM
239 * This is because of the clipping */
240 for (i=0; i<2; i++) {
241 am=i%2;
242 fprintf(out, "gsave\n");
243 if (am) {
244 clip_to_box(1.25, 0.5, 4.25, 9.5);
245 } else {
246 clip_to_box(5.0, 0.5, 8.0, 9.5);
247 }
248 for (temp_cel = ce_list; temp_cel; temp_cel=temp_cel->next) {
249 if (temp_cel->mcale.cale.description == NULL) {
250 continue;
251 }
252 if (temp_cel->mcale.cale.event) {
253 strcpy(str, " ");
254 if (!am) {
255 continue;
256 }
257 x=indent1;
258 y=default_y - defaults1 * step;
259 defaults1++;
260 } else {
261 hour24 = temp_cel->mcale.cale.begin.tm_hour;
262 if ((hour24 > 11) && (am)) {
263 continue;
264 }
265 if ((hour24 < 12) && (!am)) {
266 continue;
267 }
268
269 get_pref_time_no_secs(datef);
270 strftime(str, sizeof(str), datef, &temp_cel->mcale.cale.begin);
271
272 if (hour24 > 11) {
273 x=indent2;
274 y=top_y - (hour24 - 12) * 0.5 - (hours[hour24]) * step;
275 hours[hour24]++;
276 if (hours[hour24] > max_per_line) {
277 y=default_y - defaults2 * step;
278 defaults2++;
279 }
280 } else {
281 x=indent1;
282 y=top_y - (hour24) * 0.5 - (hours[hour24]) * step;
283 hours[hour24]++;
284 if (hours[hour24] > max_per_line) {
285 y=default_y - defaults1 * step;
286 defaults1++;
287 }
288 }
289 }
290 if (temp_cel->mcale.cale.description) {
291 strcat(str, " ");
292 strncat(str, temp_cel->mcale.cale.description, sizeof(str)-strlen(str)-2);
293 str[128]='\0';
294 /* FIXME: Add location in parentheses (loc) as the Palm does.
295 * We would need to check strlen, etc., before adding */
296 }
297 if (y > 1.0) {
298 puttext(x, y, str);
299 } else {
300 jp_logf(JP_LOG_WARN, "Too many appointments, dropping one\n");
301 }
302 }
303 fprintf(out, "grestore\n");
304 }
305
306 return EXIT_SUCCESS;
307 }
308
309 int print_days_appts(struct tm *date)
310 {
311 CalendarEventList *ce_list;
312
313 out = print_open();
314 if (!out) {
315 return EXIT_FAILURE;
316 }
317
318 ce_list = NULL;
319
320 get_days_calendar_events2(&ce_list, date, 2, 2, 2, CATEGORY_ALL, NULL);
321
322 print_dayview(date, ce_list);
323
324 print_close(out);
325
326 free_CalendarEventList(&ce_list);
327
328 return EXIT_SUCCESS;
329 }
330
331 static int f_indent_print(FILE *f, int indent, char *str) {
332 char *P;
333 int i, col;
334
335 col=indent;
336 for (P=str; *P; P++) {
337 col++;
338 if ((*P==10) || (*P==13)) {
339 fprintf(f, "%c", *P);
340 for (i=indent; i; i--) {
341 fprintf(f, " ");
342 }
343 col=indent;
344 continue;
345 }
346 if (col>75) {
347 fprintf(f, "\n");
348 for (i=indent; i; i--) {
349 fprintf(f, " ");
350 }
351 col=indent+1;
352 }
353 fprintf(f, "%c", *P);
354 }
355 return EXIT_SUCCESS;
356 }
357
358 /*----------------------------------------------------------------------
359 * ps_strncat Escapes brackets for printing in PostScript strings
360 *----------------------------------------------------------------------*/
361
362 void ps_strncat(char *dest, const char *src, int n)
363 {
364 int i = 0, j = 0;
365 char *dest2;
366 dest2 = strchr(dest, '\0');
367 while (j < n) {
368 if (src[i] == '\0') {
369 dest2[j]='\0';
370 break;
371 }
372 if (strchr("()", src[i]) != NULL) {
373 if(j<n-1) dest2[j] = '\\'; else dest2[j]=' ';
374 j++;
375 }
376 dest2[j] = src[i];
377 i++;
378 j++;
379 }
380 }
381
382 /*----------------------------------------------------------------------
383 * days_in_mon Returns the number of days in the month containing the
384 * date passed in.
385 *----------------------------------------------------------------------*/
386
387 static int days_in_mon(struct tm *date)
388 {
389 int days_in_month[]={ 31,28,31,30,31,30,31,31,30,31,30,31 };
390
391 if ((date->tm_year%4 == 0) &&
392 !(((date->tm_year+1900)%100==0) && ((date->tm_year+1900)%400!=0))) {
393 days_in_month[1]++;
394 }
395 return(days_in_month[date->tm_mon]);
396 }
397
398 /*----------------------------------------------------------------------
399 * print_months_appts Function to print the current month's
400 * appointments.
401 *----------------------------------------------------------------------*/
402
403 static const char *MonthNames[] = {
404 "January", "February", "March", "April", "May", "June", "July",
405 "August", "September", "October", "November", "December"
406 };
407
408 int print_months_appts(struct tm *date_in, PaperSize paper_size)
409 {
410 CalendarEventList *ce_list;
411 CalendarEventList *temp_cel;
412 struct tm date;
413 char desc[100];
414 time_t ltime;
415 int dow;
416 int ndim;
417 int n;
418 long fdow;
419 int mask;
420 #ifdef ENABLE_DATEBK
421 int cat_bit;
422 int db3_type;
423 long use_db3_tags;
424 struct db4_struct db4;
425 #endif
426 #ifdef HAVE_LOCALE_H
427 char *current_locale;
428 #endif
429
430 /*------------------------------------------------------------------
431 * Set up the PostScript output file, and print the header to it.
432 *------------------------------------------------------------------*/
433 mask=0;
434
435 time(<ime);
436
437 #ifdef ENABLE_DATEBK
438 get_pref(PREF_USE_DB3, &use_db3_tags, NULL);
439 #endif
440
441 #ifdef HAVE_LOCALE_H
442 current_locale = setlocale(LC_NUMERIC,"C");
443 #endif
444 if (! (out = print_open())) return(EXIT_FAILURE);
445
446 fprintf(out,
447 "%%!PS-Adobe-2.0\n"
448 "%%%%Creator: J-Pilot\n"
449 "%%%%CreationDate: %s"
450 "%%%%DocumentData: Clean7Bit\n"
451 "%%%%Orientation: Landscape\n\n"
452 "%%DocumentFonts: Times-Roman Times-Bold Courier Courier-Bold\n"
453 "%%%%Magnification: 1.0000\n"
454 "%%%%Pages: 1\n"
455 "%%%%EndComments\n"
456 "%%%%BeginProlog\n"
457 ,ctime(<ime));
458 fprintf(out, "/PageSize (%s) def\n\n", PaperSizes[paper_size]);
459 print_common_prolog(out);
460 fprintf(out,
461 "%%%%EndProlog\n"
462 "%%%%BeginSetup\n");
463 print_common_setup(out);
464 print_month_header(out);
465 fprintf(out,
466 "%%%%EndSetup\n"
467 "%%%%Page: 1 1\n\n");
468
469 /*------------------------------------------------------------------
470 * Extract the appointments
471 *------------------------------------------------------------------*/
472 ce_list = NULL;
473 memcpy(&date, date_in, sizeof(struct tm));
474 /* Get all of the appointments */
475
476 get_days_calendar_events2(&ce_list, NULL, 2, 2, 2, CATEGORY_ALL, NULL);
477 get_month_info(date.tm_mon, 1, date.tm_year, &dow, &ndim);
478 weed_calendar_event_list(&ce_list, date.tm_mon, date.tm_year, 0, &mask);
479
480 /*------------------------------------------------------------------
481 * Loop through the days in the month, printing appointments
482 *------------------------------------------------------------------*/
483 date.tm_mday=1;
484 date.tm_sec=0;
485 date.tm_min=0;
486 date.tm_hour=11;
487 date.tm_isdst=-1;
488 mktime(&date);
489
490 get_pref(PREF_FDOW, &fdow, NULL);
491
492 fprintf(out,
493 "(%s %d) %d (%s) (%s version %s) %ld InitialisePage\n\n",
494 MonthNames[date_in->tm_mon], date_in->tm_year + 1900,
495 date.tm_wday,
496 ctime(<ime),
497 PN, VERSION, fdow);
498
499 for (n=0, date.tm_mday=1; date.tm_mday<=ndim; date.tm_mday++, n++) {
500 date.tm_sec=0;
501 date.tm_min=0;
502 date.tm_hour=11;
503 date.tm_isdst=-1;
504 date.tm_wday=0;
505 date.tm_yday=1;
506 mktime(&date);
507
508 fprintf(out, "%%--------------------------------------------------\n"
509 "%%Stuff for day %2d being printed\n", date.tm_mday);
510 fprintf(out, "NextDay\n");
511
512 for (temp_cel = ce_list; temp_cel; temp_cel=temp_cel->next) {
513 #ifdef ENABLE_DATEBK
514 if (use_db3_tags) {
515 db3_parse_tag(temp_cel->mcale.cale.note, &db3_type, &db4);
516 /* jp_logf(JP_LOG_DEBUG, "category = 0x%x\n", db4.category); */
517 cat_bit=1<<db4.category;
518 if (!(cat_bit & datebk_category)) {
519 jp_logf(JP_LOG_DEBUG, "skipping rec not in this category\n");
520 continue;
521 }
522 }
523 #endif
524 if (calendar_isApptOnDate(&(temp_cel->mcale.cale), &date)) {
525 char tmp[20];
526 char datef1[20];
527 char datef2[20];
528 tmp[0]='\0';
529 if ( ! temp_cel->mcale.cale.event) {
530 get_pref_time_no_secs(datef1);
531 g_snprintf(datef2, sizeof(datef2), "(%s )", datef1);
532 strftime(tmp, sizeof(tmp), datef2, &(temp_cel->mcale.cale.begin));
533 tmp[19]='\0';
534 }
535 desc[0]='\0';
536 if (temp_cel->mcale.cale.description) {
537 ps_strncat(desc, temp_cel->mcale.cale.description, 100);
538 desc[sizeof(desc)-1]='\0';
539 /* FIXME: Add location in parentheses (loc) as the Palm does.
540 * We would need to check strlen, etc., before adding */
541 }
542 remove_cr_lfs(desc);
543 fprintf(out, "%s (%s) %simedItem\n", tmp, desc,
544 (strlen(tmp) == 0) ? "Unt" : "T" );
545 }
546 }
547 }
548
549 /*------------------------------------------------------------------*/
550 memcpy(&date, date_in, sizeof(struct tm));
551 date.tm_mday = 1; /* Go to the first of the month */
552 mktime(&date);
553 sub_months_from_date(&date, 1);
554 strftime(desc, sizeof(desc), "(%B %Y) %w ", &date);
555 fprintf(out, "\n\n%%----------------------------------------\n"
556 "%% Now generate the small months\n\n"
557 "%s %d ", desc, days_in_mon(&date));
558
559 add_months_to_date(&date, 2);
560 strftime(desc, sizeof(desc), "(%B %Y) %w ", &date);
561 fprintf(out, "%s %d SmallMonths\n", desc, days_in_mon(&date));
562
563 /*------------------------------------------------------------------*/
564
565 free_CalendarEventList(&ce_list);
566
567 fprintf(out, "grestore\n");
568 print_logo(out, 20, 30, 0.35);
569 fprintf(out, "\nshowpage\n");
570 fprintf(out, "%%%%EOF\n");
571
572 print_close(out);
573
574 #ifdef HAVE_LOCALE_H
575 setlocale(LC_NUMERIC, current_locale);
576 #endif
577 return EXIT_SUCCESS;
578 }
579
580 /*----------------------------------------------------------------------
581 * reset_first_last Routine to reset max/min appointment times
582 *----------------------------------------------------------------------*/
583
584 static void reset_first_last(void)
585 {
586 first_hour = 25;
587 first_min = 61;
588 last_hour = -1;
589 last_min = -1;
590 }
591
592 /*----------------------------------------------------------------------
593 * check_first_last Routine to track max/min appointment times
594 *----------------------------------------------------------------------*/
595
596 static void check_first_last(CalendarEventList *cel)
597 {
598 struct tm *ApptTime;
599 ApptTime = &(cel->mcale.cale.begin);
600 if (ApptTime->tm_hour == first_hour) {
601 if (ApptTime->tm_min < first_min) first_min = ApptTime->tm_min;
602 }
603 else if (ApptTime->tm_hour < first_hour) {
604 first_hour = ApptTime->tm_hour;
605 first_min = ApptTime->tm_min;
606 }
607
608 ApptTime = &(cel->mcale.cale.end);
609 if (ApptTime->tm_hour == last_hour) {
610 if (ApptTime->tm_min > last_min) last_min = ApptTime->tm_min;
611 } else if (ApptTime->tm_hour > last_hour) {
612 last_hour = ApptTime->tm_hour;
613 last_min = ApptTime->tm_min;
614 }
615 }
616
617 /*----------------------------------------------------------------------
618 * print_weeks_appts Function to print a weeks appointments onto a
619 * weekly plan. We assume that date_in is the chosen
620 * first day of the week.
621 *----------------------------------------------------------------------*/
622
623 int print_weeks_appts(struct tm *date_in, PaperSize paper_size)
624 {
625 CalendarEventList *ce_list, *temp_cel;
626 struct tm date;
627 struct tm *today_date;
628 char desc[256], short_date[32];
629 int n;
630 time_t ltime;
631 #ifdef ENABLE_DATEBK
632 int cat_bit;
633 int db3_type;
634 long use_db3_tags;
635 struct db4_struct db4;
636 #endif
637 #ifdef HAVE_LOCALE_H
638 char *current_locale;
639 #endif
640
641 #ifdef ENABLE_DATEBK
642 get_pref(PREF_USE_DB3, &use_db3_tags, NULL);
643 #endif
644 #ifdef HAVE_LOCALE_H
645 current_locale = setlocale(LC_NUMERIC,"C");
646 #endif
647
648 /*------------------------------------------------------------------
649 * Set up the PostScript output file, and print the header to it.
650 *------------------------------------------------------------------*/
651 if (! (out = print_open())) return(EXIT_FAILURE);
652
653 time(<ime);
654 fprintf(out,
655 "%%!PS-Adobe-2.0\n"
656 "%%%%Creator: J-Pilot\n"
657 "%%%%CreationDate: %s"
658 "%%%%DocumentData: Clean7Bit\n"
659 "%%%%Orientation: Landscape\n"
660 "%%DocumentFonts: Times-Roman Times-Bold Courier Courier-Bold\n"
661 "%%%%Magnification: 1.0000\n"
662 "%%%%Pages: 1\n"
663 "%%%%EndComments\n"
664 "%%%%BeginProlog\n"
665 ,ctime(<ime));
666 /*------------------------------------------------------------------
667 * These are preferences for page size (passed in), first and last
668 * hours on the plan (default; scales if earlier or later are present),
669 * and whether to print dashes across the page.
670 *------------------------------------------------------------------*/
671 fprintf(out, "/PageSize (%s) def\n\n", PaperSizes[paper_size]);
672 fprintf(out, "/FirstHour 9 def\n"
673 "/LastHour 22 def\n");
674 fprintf(out, "/Dashes true def\n");
675 print_common_prolog(out);
676 fprintf(out,
677 "%%%%EndProlog\n"
678 "%%%%BeginSetup\n");
679 print_common_setup(out);
680 print_week_header(out);
681 fprintf(out,
682 "%%%%EndSetup\n"
683 "%%%%Page: 1 1\n\n");
684
685 /*------------------------------------------------------------------
686 * Run through the appointments, looking for earliest and latest
687 *------------------------------------------------------------------*/
688 ce_list = NULL;
689 get_days_calendar_events2(&ce_list, NULL, 2, 2, 2, CATEGORY_ALL, NULL);
690 reset_first_last();
691
692 memcpy(&date, date_in, sizeof(struct tm));
693 for (n = 0; n < 7; n++, add_days_to_date(&date, 1)) {
694 for (temp_cel = ce_list; temp_cel; temp_cel=temp_cel->next) {
695 #ifdef ENABLE_DATEBK
696 if (use_db3_tags) {
697 db3_parse_tag(temp_cel->mcale.cale.note, &db3_type, &db4);
698 cat_bit=1<<db4.category;
699 if (!(cat_bit & datebk_category)) continue;
700 }
701 #endif
702 if (calendar_isApptOnDate(&(temp_cel->mcale.cale), &date))
703 if (! temp_cel->mcale.cale.event)
704 check_first_last(temp_cel);
705 }
706 }
707 if (last_min > 0) last_hour++;
708
709 /*------------------------------------------------------------------
710 * Now put in the finishing touches to the header, and kick-start
711 * the printing process
712 *------------------------------------------------------------------*/
713
714 today_date = localtime(<ime);
715 fprintf(out,
716 "%%------------------------------------------------------------\n"
717 "%% This is today's date, the date of printing, plus the hour\n"
718 "%% before & after the first and last appointments, respectively\n"
719 "%d %d %d %d %d startprinting\n\n",
720 today_date->tm_mday, today_date->tm_mon + 1,
721 today_date->tm_year + 1900, first_hour, last_hour);
722 fprintf(out, "( by %s version %s) show\n", PN, VERSION);
723
724 print_logo(out, 20, 30, 0.35);
725
726 /*------------------------------------------------------------------
727 * Run through the appointments, printing them out
728 *------------------------------------------------------------------*/
729 free_CalendarEventList(&ce_list);
730 ce_list = NULL;
731
732 /* Get all of the appointments */
733 get_days_calendar_events2(&ce_list, NULL, 2, 2, 2, CATEGORY_ALL, NULL);
734
735 /* iterate through seven days */
736 memcpy(&date, date_in, sizeof(struct tm));
737
738 for (n = 0; n < 7; n++, add_days_to_date(&date, 1)) {
739 strftime(short_date, sizeof(short_date), "%a, %d %b, %Y", &date);
740 fprintf(out, "%d startday\n(%s) dateline\n", n, short_date);
741
742 for (temp_cel = ce_list; temp_cel; temp_cel=temp_cel->next) {
743 #ifdef ENABLE_DATEBK
744 if (use_db3_tags) {
745 db3_parse_tag(temp_cel->mcale.cale.note, &db3_type, &db4);
746 jp_logf(JP_LOG_DEBUG, "category = 0x%x\n", db4.category);
747 cat_bit=1<<db4.category;
748 if (!(cat_bit & datebk_category)) {
749 jp_logf(JP_LOG_DEBUG, "skip rec not in this category\n");
750 continue;
751 }
752 }
753 #endif
754 if (calendar_isApptOnDate(&(temp_cel->mcale.cale), &date)) {
755 memset(desc, 0, sizeof(desc));
756 memset(short_date, 0, sizeof(short_date));
757
758 if ( ! temp_cel->mcale.cale.event)
759 {
760 char t1[6], t2[6], ht[3], mt[3];
761 int j, m;
762
763 strftime(ht, sizeof(ht), "%H", &(temp_cel->mcale.cale.begin));
764 strftime(mt, sizeof(mt), "%M", &(temp_cel->mcale.cale.begin));
765 m = atoi(mt);
766 snprintf(t1, sizeof(t1), "%s.%02d", ht, (int)((m * 100.)/60));
767
768 strftime(ht, sizeof(ht), "%H", &(temp_cel->mcale.cale.end));
769 strftime(mt, sizeof(mt), "%M", &(temp_cel->mcale.cale.end));
770 m = atoi(mt);
771 snprintf(t2, sizeof(t2), "%s.%02d", ht, (int)((m * 100.)/60));
772 sprintf(short_date, "%s %s ", t1, t2);
773 for (j=0; j<30;j++) short_date[j] =tolower(short_date[j]);
774 }
775 if (temp_cel->mcale.cale.description) {
776 ps_strncat(desc, temp_cel->mcale.cale.description, 250);
777 /* FIXME: Add location in parentheses (loc) as the Palm does.
778 * We would need to check strlen, etc., before adding */
779 remove_cr_lfs(desc);
780 }
781 fprintf(out, "%s (%s) itemline\n", short_date, desc);
782 }
783 }
784 }
785 free_CalendarEventList(&ce_list);
786 fprintf(out, "\nfinishprinting\n");
787 fprintf(out, "%%%%EOF\n");
788 print_close(out);
789
790 #ifdef HAVE_LOCALE_H
791 setlocale(LC_ALL, current_locale);
792 #endif
793 return EXIT_SUCCESS;
794 }
795
796 /*
797 * Address code
798 */
799
800 static int print_address_header(void)
801 {
802 time_t ltime;
803 struct tm *date;
804 const char *svalue;
805 char str[256];
806
807 time(<ime);
808 date = localtime(<ime);
809
810 get_pref(PREF_SHORTDATE, NULL, &svalue);
811 strftime(str, sizeof(str), svalue, date);
812
813 fprintf(out,
814 "%%!PS-Adobe-2.0\n"
815 "%%%%Creator: J-Pilot\n"
816 "%%%%CreationDate: %s"
817 "%%%%DocumentData: Clean7Bit\n"
818 /* XXX Title */
819 "%%%%Orientation: Portrait\n"
820 /* XXX BoundingBox */
821 "%%DocumentFonts: Times-Roman Times-Bold "
822 "Courier Courier-Bold ZapfDingbats\n"
823 "%%%%Magnification: 1.0000\n"
824 "%%%%BoundingBox: 36 36 576 756\n"
825 "%%%%EndComments\n",
826 ctime(<ime));
827 fprintf(out,
828 "%%%%BeginProlog\n"
829 "%%%%BeginResource: procset\n"
830 "/inch {72 mul} def\n"
831 "/left {0.5 inch} def\n"
832 "/bottom {1.0 inch} def\n"
833 "/bottom_hline {2.0 inch} def\n"
834 "/footer {0.9 inch} def\n"
835 "/top {10.5 inch 14 sub} def\n"
836 "/buffer 1024 string def\n"
837 "/scratch 128 string def\n"
838 "/printobject {\n"
839 "dup 128 string cvs dup (--nostringval--) eq {\n"
840 "pop type24 string cvs\n"
841 "}{\n"
842 "exch pop\n"
843 "} ifelse\n"
844 "} bind def\n");
845 /* Checkbox stuff */
846 fprintf(out,
847 "/checkboxcheck {\n"
848 "%%currentpoint 6 add moveto\n"
849 "%%4 -5 rlineto\n"
850 "%%6 12 rlineto\n"
851 "/ZapfDingbats 14 selectfont (4) show\n" /* or 3 if you prefer */
852 "} bind def\n"
853 "/checkboxbox {\n"
854 "8 0 rlineto\n"
855 "0 8 rlineto\n"
856 "-8 0 rlineto\n"
857 "0 -8 rlineto\n"
858 "} bind def\n"
859 "/checkbox {\n"
860 "currentpoint\n"
861 "gsave\n"
862 "newpath\n"
863 "moveto\n"
864 "1 setlinewidth\n"
865 "checkboxbox\n"
866 "stroke\n"
867 "grestore\n"
868 "} bind def\n"
869 "/checkedbox {\n"
870 "currentpoint\n"
871 "gsave\n"
872 "newpath\n"
873 "moveto\n"
874 "1 setlinewidth\n"
875 "checkboxbox\n"
876 "checkboxcheck\n"
877 "stroke\n"
878 "grestore\n"
879 "} bind def\n"
880 );
881
882 /* Recode font function */
883 fprintf(out,
884 "/Recode {\n"
885 "exch\n"
886 "findfont\n"
887 "dup length dict\n"
888 "begin\n"
889 "{ def\n"
890 "} forall\n"
891 "/Encoding ISOLatin1Encoding def\n"
892 "currentdict\n"
893 "end\n"
894 "definefont pop\n"
895 "} bind def\n");
896 fprintf(out,
897 "/Times-Roman /Times-Roman-ISOLatin1 Recode\n"
898 "/Courier /Courier-ISOLatin1 Recode\n"
899 "/Courier-Bold /Courier-Bold-ISOLatin1 Recode\n");
900 fprintf(out,
901 "/hline {\n"
902 "currentpoint 1 add currentpoint 1 add\n"
903 "currentpoint 4 add currentpoint 4 add\n"
904 "gsave\n"
905 "newpath\n"
906 "moveto\n"
907 "exch\n"
908 "1.0 inch add\n"
909 "exch\n"
910 "7 setlinewidth\n"
911 "lineto\n"
912 "stroke\n"
913 "%%\n"
914 "newpath\n"
915 "moveto\n"
916 "exch\n"
917 "7.5 inch add\n"
918 "exch\n"
919 "1 setlinewidth\n"
920 "lineto\n"
921 "stroke\n"
922 "grestore\n"
923 "} bind def\n"
924 "%%\n"
925 "%%\n");
926 fprintf(out,
927 "/setup\n"
928 "{\n"
929 "/Times-Roman-ISOLatin1 10 selectfont\n"
930 "left footer moveto\n"
931 "(%s) show\n"
932 "7.5 inch footer moveto\n"
933 "(J-Pilot) show\n"
934 "%% This assumes that the prev page number is on the stack\n"
935 "4.25 inch footer moveto\n"
936 "1 add dup printobject show\n"
937 "/Courier-ISOLatin1 12 selectfont\n"
938 "left top moveto\n"
939 "} bind def\n"
940 "/printit\n"
941 "{\n"
942 "{ %%loop\n"
943 "currentfile buffer readline { %%ifelse\n"
944 "("Q_FLAG_CHAR"LINEFEED) search { %%if\n"
945 "pop pop pop showpage setup ( )\n"
946 "currentpoint 14 add moveto\n"
947 "} if\n"
948 "("Q_FLAG_CHAR"HLINE) search { %%if\n"
949 "currentpoint exch pop bottom_hline le { %%if\n"
950 "pop pop pop\n"
951 "showpage setup\n"
952 "0 0 0\n"
953 "} if\n"
954 "hline\n"
955 "pop pop pop ( )\n"
956 "} if\n"
957 "("Q_FLAG_CHAR"END) search { %%if\n"
958 " showpage stop\n"
959 "} if\n"
960 "("Q_FLAG_CHAR"C12) search {\n"
961 "/Courier-ISOLatin1 12 selectfont\n"
962 "currentpoint 14 add moveto\n"
963 "pop pop pop ( )\n"
964 "} if\n"
965 "("Q_FLAG_CHAR"CB12) search {\n"
966 "/Courier-Bold-ISOLatin1 12 selectfont\n"
967 "currentpoint 14 add moveto\n"
968 "pop pop pop ( )\n"
969 "} if\n",
970 str
971 );
972 /* Check box */
973 fprintf(out,
974 "("Q_FLAG_CHAR"CHECKBOX) search {\n"
975 "currentpoint exch pop bottom_hline le {\n"
976 "pop pop pop\n"
977 "showpage setup\n"
978 "0 0 0\n"
979 "} if\n"
980 "checkbox\n"
981 "currentpoint 14 add moveto\n"
982 "pop pop pop ( )\n"
983 "} if\n"
984 );
985 /* Check box */
986 fprintf(out,
987 "("Q_FLAG_CHAR"CHECKEDBOX) search {\n"
988 "currentpoint exch pop bottom_hline le {\n"
989 "pop pop pop\n"
990 "showpage setup\n"
991 "0 0 0\n"
992 "} if\n"
993 "checkedbox\n"
994 "currentpoint 14 add moveto\n"
995 "pop pop pop ( )\n"
996 "} if\n"
997 );
998 fprintf(out,
999 "%%%%EndResource\n"
1000 "%%%%EndProlog\n"); /* XXX not exactly sure about position */
1001
1002 fprintf(out,
1003 "gsave show grestore\n"
1004 "currentpoint 14 sub moveto\n"
1005 "currentpoint exch pop bottom le { %%if\n"
1006 "showpage setup\n"
1007 "} if\n"
1008 "}{ %%else\n"
1009 "showpage exit\n"
1010 "} ifelse\n"
1011 "} loop\n"
1012 "} bind def\n"
1013 "0 %%The page number minus 1\n"
1014 "setup printit\n"
1015 );
1016 return EXIT_SUCCESS;
1017 }
1018
1019
1020 int print_contacts(ContactList *contact_list,
1021 struct ContactAppInfo *contact_app_info,
1022 address_schema_entry *schema, int schema_size)
1023 {
1024 long one_rec_per_page;
1025 long lines_between_recs;
1026 ContactList *temp_cl;
1027 MyContact *mcont;
1028 int show1, show2, show3;
1029 int i;
1030 int address_i, phone_i, IM_i;
1031 char str[100];
1032 char spaces[24];
1033 char birthday_str[255];
1034 const char *pref_date;
1035 char *utf;
1036 long char_set;
1037 #ifdef HAVE_LOCALE_H
1038 char *current_locale;
1039 #endif
1040
1041 out = print_open();
1042 if (!out) {
1043 return EXIT_FAILURE;
1044 }
1045
1046 #ifdef HAVE_LOCALE_H
1047 current_locale = setlocale(LC_NUMERIC,"C");
1048 #endif
1049
1050 memset(spaces, ' ', sizeof(spaces));
1051
1052 get_pref(PREF_CHAR_SET, &char_set, NULL);
1053
1054 print_address_header();
1055
1056 switch (addr_sort_order) {
1057 case SORT_BY_LNAME:
1058 default:
1059 show1=contLastname;
1060 show2=contFirstname;
1061 show3=contCompany;
1062 break;
1063 case SORT_BY_FNAME:
1064 show1=contFirstname;
1065 show2=contLastname;
1066 show3=contCompany;
1067 break;
1068 case SORT_BY_COMPANY:
1069 show1=contCompany;
1070 show2=contLastname;
1071 show3=contFirstname;
1072 break;
1073 }
1074
1075 get_pref(PREF_PRINT_ONE_PER_PAGE, &one_rec_per_page, NULL);
1076 get_pref(PREF_NUM_BLANK_LINES, &lines_between_recs, NULL);
1077
1078 for (temp_cl = contact_list; temp_cl; temp_cl=temp_cl->next) {
1079
1080 fprintf(out, "%cHLINE\n", FLAG_CHAR);
1081
1082 str[0]='\0';
1083 if (temp_cl->mcont.cont.entry[show1] || temp_cl->mcont.cont.entry[show2]) {
1084 if (temp_cl->mcont.cont.entry[show1] && temp_cl->mcont.cont.entry[show2]) {
1085 g_snprintf(str, sizeof(str), "%s, %s", temp_cl->mcont.cont.entry[show1], temp_cl->mcont.cont.entry[show2]);
1086 }
1087 if (temp_cl->mcont.cont.entry[show1] && ! temp_cl->mcont.cont.entry[show2]) {
1088 strncpy(str, temp_cl->mcont.cont.entry[show1], 48);
1089 }
1090 if (! temp_cl->mcont.cont.entry[show1] && temp_cl->mcont.cont.entry[show2]) {
1091 strncpy(str, temp_cl->mcont.cont.entry[show2], 48);
1092 }
1093 } else if (temp_cl->mcont.cont.entry[show3]) {
1094 strncpy(str, temp_cl->mcont.cont.entry[show3], 48);
1095 } else {
1096 strcpy(str, "-Unnamed-");
1097 }
1098
1099 courier_bold_12();
1100 fprintf(out, "%s\n", str);
1101 courier_12();
1102
1103 mcont = &(temp_cl->mcont);
1104 address_i=phone_i=IM_i=0;
1105 for (i=0; i<schema_size; i++) {
1106 /* Get the entry texts */
1107 if (mcont->cont.entry[schema[i].record_field]) {
1108 switch (schema[i].type) {
1109 case ADDRESS_GUI_IM_MENU_TEXT:
1110 g_snprintf(str, 18, "%s:%s", contact_app_info->IMLabels[mcont->cont.IMLabel[IM_i]], spaces);
1111 fprintf(out, "%s", str);
1112 IM_i++;
1113 break;
1114 case ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT:
1115 g_snprintf(str, 18, "%s:%s", contact_app_info->phoneLabels[mcont->cont.phoneLabel[phone_i]], spaces);
1116 fprintf(out, "%s", str);
1117 phone_i++;
1118 break;
1119 case ADDRESS_GUI_ADDR_MENU_TEXT:
1120 g_snprintf(str, 18, "%s:%s", contact_app_info->addrLabels[mcont->cont.addressLabel[address_i]], spaces);
1121 fprintf(out, "%s", str);
1122 address_i++;
1123 break;
1124 default:
1125 if (contact_app_info->labels[schema[i].record_field]) {
1126 utf = charset_p2newj(contact_app_info->labels[schema[i].record_field], 16, char_set);
1127 g_snprintf(str, 18, "%s:%s", utf, spaces);
1128 fprintf(out, "%s", str);
1129 g_free(utf);
1130 }
1131 else {
1132 g_snprintf(str, 18, ":%s", spaces);
1133 fprintf(out, "%s", str);
1134 }
1135 }
1136 switch (schema[i].type) {
1137 case ADDRESS_GUI_LABEL_TEXT:
1138 case ADDRESS_GUI_DIAL_SHOW_PHONE_MENU_TEXT:
1139 case ADDRESS_GUI_IM_MENU_TEXT:
1140 case ADDRESS_GUI_ADDR_MENU_TEXT:
1141 case ADDRESS_GUI_WEBSITE_TEXT:
1142 f_indent_print(out, 17, mcont->cont.entry[schema[i].record_field]);
1143 fprintf(out, "\n");
1144 break;
1145 case ADDRESS_GUI_BIRTHDAY:
1146 if (mcont->cont.birthdayFlag) {
1147 birthday_str[0]='\0';
1148 get_pref(PREF_SHORTDATE, NULL, &pref_date);
1149 strftime(birthday_str, sizeof(birthday_str), pref_date, &(mcont->cont.birthday));
1150 g_snprintf(str, 18, "%s:%s", contact_app_info->labels[schema[i].record_field] ? contact_app_info->labels[schema[i].record_field] : "",
1151 spaces);
1152 fprintf(out, "%s", str);
1153 f_indent_print(out, 17, birthday_str);
1154 fprintf(out, "\n");
1155 }
1156 break;
1157 }
1158 }
1159 }
1160
1161 if (one_rec_per_page) {
1162 fprintf(out, "%cLINEFEED\n", FLAG_CHAR);
1163 } else {
1164 for (i=lines_between_recs; i>0; i--) {
1165 fprintf(out, "\n");
1166 }
1167 }
1168 }
1169
1170 print_close(out);
1171
1172 #ifdef HAVE_LOCALE_H
1173 setlocale(LC_ALL, current_locale);
1174 #endif
1175
1176 return EXIT_SUCCESS;
1177 }
1178
1179 /*
1180 * ToDo code
1181 */
1182 int print_todos(ToDoList *todo_list, char *category_name)
1183 {
1184 long one_rec_per_page;
1185 long lines_between_recs;
1186 ToDoList *temp_l;
1187 struct ToDo *todo;
1188 int indent;
1189 const char *datef;
1190 char str[100];
1191 time_t ltime;
1192 struct tm *now;
1193 #ifdef HAVE_LOCALE_H
1194 char *current_locale;
1195 #endif
1196
1197 out = print_open();
1198 if (!out) {
1199 return EXIT_FAILURE;
1200 }
1201
1202 #ifdef HAVE_LOCALE_H
1203 current_locale = setlocale(LC_NUMERIC,"C");
1204 #endif
1205
1206 fprintf(out, "%%!PS-Adobe-2.0\n\n"
1207 "/PageSize (%s) def\n\n", PaperSizes[PAPER_Letter]);
1208 print_common_prolog(out);
1209 print_common_setup(out);
1210 fprintf(out, "/CategoryName (%s) def\n", category_name);
1211 print_todo_header(out);
1212
1213 get_pref(PREF_PRINT_ONE_PER_PAGE, &one_rec_per_page, NULL);
1214 get_pref(PREF_NUM_BLANK_LINES, &lines_between_recs, NULL);
1215
1216 get_pref(PREF_SHORTDATE, NULL, &datef);
1217 time(<ime);
1218 now = localtime(<ime);
1219 strftime(str, sizeof(str), datef, now);
1220 indent=strlen(str) + 8;
1221
1222 for (temp_l = todo_list; temp_l; temp_l=temp_l->next) {
1223 todo = &(temp_l->mtodo.todo);
1224
1225 fprintf(out, todo->complete ? "true " : "false ");
1226
1227 fprintf(out, "%d ", todo->priority);
1228
1229 if (todo->indefinite) {
1230 sprintf(str, "%s ", "No Due");
1231 str[indent-8]='\0';
1232 } else {
1233 strftime(str, sizeof(str), datef, &(todo->due));
1234 }
1235 fprintf(out, "(%s) ", str);
1236
1237 if (todo->description) {
1238 int len;
1239 char *buf;
1240
1241 len = strlen(todo->description);
1242 buf = malloc(2 * len + 1);
1243 memset(buf, 0, 2 * len + 1);
1244 ps_strncat(buf, todo->description, 2 * len);
1245
1246 fprintf(out, "(%s) ", buf);
1247 free(buf);
1248 } else {
1249 fprintf(out, "() ");
1250 }
1251
1252 if ((todo->note) && todo->note[0]) {
1253 int len;
1254 char *buf;
1255
1256 len = strlen(todo->note);
1257 buf = malloc(2 * len + 1);
1258 memset(buf, 0, 2 * len + 1);
1259 ps_strncat(buf, todo->note, 2 * len);
1260
1261 fprintf(out, "(%s) ", buf);
1262 free(buf);
1263 } else {
1264 fprintf(out, "()");
1265 }
1266 fprintf(out, " Todo\n");
1267
1268 if (one_rec_per_page) {
1269 fprintf(out, "NewPage\n");
1270 }
1271 }
1272 fprintf(out, "showpage\n");
1273
1274 print_close(out);
1275
1276 #ifdef HAVE_LOCALE_H
1277 setlocale(LC_ALL, current_locale);
1278 #endif
1279
1280 return EXIT_SUCCESS;
1281 }
1282 /*
1283 * Memo code
1284 */
1285 int print_memos(MemoList *memo_list)
1286 {
1287 long one_rec_per_page;
1288 long lines_between_recs;
1289 MemoList *temp_l;
1290 struct Memo *memo;
1291 int i;
1292 #ifdef HAVE_LOCALE_H
1293 char *current_locale;
1294 #endif
1295
1296 out = print_open();
1297 if (!out) {
1298 return EXIT_FAILURE;
1299 }
1300
1301 #ifdef HAVE_LOCALE_H
1302 current_locale = setlocale(LC_NUMERIC,"C");
1303 #endif
1304
1305 print_address_header();
1306
1307 get_pref(PREF_PRINT_ONE_PER_PAGE, &one_rec_per_page, NULL);
1308 get_pref(PREF_NUM_BLANK_LINES, &lines_between_recs, NULL);
1309
1310 courier_12();
1311
1312 for (temp_l = memo_list; temp_l; temp_l=temp_l->next) {
1313 memo = &(temp_l->mmemo.memo);
1314
1315 if (memo->text) {
1316 fprintf(out, "%cHLINE\n", FLAG_CHAR);
1317 f_indent_print(out, 0, memo->text);
1318 fprintf(out, "\n");
1319 }
1320
1321 if (one_rec_per_page) {
1322 fprintf(out, "%cLINEFEED\n", FLAG_CHAR);
1323 } else {
1324 for (i=lines_between_recs; i>0; i--) {
1325 fprintf(out, "\n");
1326 }
1327 }
1328 }
1329
1330 fprintf(out, "%cEND\n", FLAG_CHAR);
1331
1332 #ifdef HAVE_LOCALE_H
1333 setlocale(LC_ALL, current_locale);
1334 #endif
1335
1336 print_close(out);
1337
1338 return EXIT_SUCCESS;
1339 }
1340