"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.
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