Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / dtcm / dtcm / format.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /*******************************************************************************
24 **
25 **  format.c
26 **
27 **  $XConsortium: format.c /main/5 1996/11/21 19:42:52 drk $
28 **
29 **  RESTRICTED CONFIDENTIAL INFORMATION:
30 **
31 **  The information in this document is subject to special
32 **  restrictions in a confidential disclosure agreement between
33 **  HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
34 **  document outside HP, IBM, Sun, USL, SCO, or Univel without
35 **  Sun's specific written approval.  This document and all copies
36 **  and derivative works thereof must be returned or destroyed at
37 **  Sun's request.
38 **
39 **  Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
40 **
41 *******************************************************************************/
42
43 /*                                                                      *
44  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
45  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
46  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
47  * (c) Copyright 1993, 1994 Novell, Inc.                                *
48  */
49
50 #ifndef lint
51 static char sccsid[] = "@(#)format.c 1.27 95/01/19 Copyr 1991 Sun Microsystems, Inc.";
52 #endif
53
54 #include <EUSCompat.h>
55 #include <stdio.h>
56 #include <sys/time.h>
57 #if defined(sun) && defined(_XOPEN_SOURCE)
58 #include <time.h>
59 #endif
60 #include <Xm/Xm.h>
61 #include <csa.h>
62 #include "util.h"
63 #include "cm_tty.h"
64 #include "timeops.h"
65 #include "format.h"
66 #include "gettext.h"
67 #include "datefield.h"
68 #include "props.h"
69
70 #define XOS_USE_XT_LOCKING
71 #define X_INCLUDE_TIME_H
72 #include <X11/Xos_r.h>
73
74 /*
75  *  Convert tick to m, d, y string.  e.g. May 1, 1988
76  */
77 extern void
78 format_date(Tick t, OrderingType order, char *buf, int day_and_date,
79         int and_date, int full_day)
80 {
81         int m, d, y, wd;
82         struct tm *tm;
83         _Xltimeparams localtime_buf;
84
85         buf[0]=NULL;
86         tm = _XLocaltime(&t, localtime_buf);
87         m = tm->tm_mon+1;
88         d = tm->tm_mday;
89         y = tm->tm_year + 1900;
90         wd = tm->tm_wday;
91
92         switch(order) {
93                 case ORDER_DMY:     
94                         /* STRING_EXTRACTION SUNW_DESKSET_CM_MSG :
95                          *
96                          * %s, %d %s %4d is a form of the date format. 
97                          * Change this to reflect your local convention.
98                          * eg. In the German locale, "%s, %d %s %4d" may be changed
99                          * to "%s. %d %s %4d".
100                          */
101                         if (day_and_date)
102                                 if (full_day)
103                                         (void)sprintf(buf, "%s, %d %s %4d", 
104                                                 days2[wd], d, months[m], y);
105                                 else
106                                         (void)sprintf(buf, "%s, %d %s %4d", 
107                                                 days[wd], d, months[m], y);
108                         else if (and_date)
109                                 (void)sprintf(buf, "%d %s %4d", d, months[m], y);
110
111                         else 
112                                 (void) sprintf(buf, "%s %4d", months[m], y);
113                         break;
114                 case ORDER_YMD:    
115                         if (day_and_date) 
116                                 if (full_day)
117                                         (void)sprintf(buf, "%s, %4d %s %d", 
118                                                 days2[wd], y, months[m], d);
119                                 else
120                                         (void)sprintf(buf, "%s, %4d %s %d", 
121                                                 days[wd], y, months[m], d);
122                         else if (and_date)
123                                 (void)sprintf(buf, "%4d %s %d", y, months[m], d);
124                         else 
125                                 (void) sprintf(buf, "%4d %s", y, months[m]);
126                         break;
127                 case ORDER_MDY:   
128                 default:
129                         if (day_and_date) 
130                                 if (full_day)
131                                         (void)sprintf(buf, "%s, %s %d %4d", 
132                                                 days2[wd], months[m], d, y);
133                                 else
134                                         (void)sprintf(buf, "%s, %s %d %4d", 
135                                                 days[wd], months[m], d, y);
136                         else if (and_date)
137                                         (void)sprintf(buf, "%s %d %4d", 
138                                                 months[m], d, y);
139                         else 
140                                 (void) sprintf(buf, "%s %4d", months[m], y);
141                         break;
142         }
143
144 }
145
146 /*
147  *  Convert tick to m/d
148  */
149 extern void
150 format_date3(Tick t, OrderingType order, SeparatorType sep, char *buf) 
151 {
152         int m, d;
153         struct tm *tm;  
154         char *str = (char *) separator_str(sep);
155         _Xltimeparams localtime_buf;
156
157         buf[0]=NULL;
158         tm = _XLocaltime(&t, localtime_buf); 
159
160         m = tm->tm_mon+1; 
161         d = tm->tm_mday;
162         switch(order) {
163                 case ORDER_YMD:    
164                 case ORDER_MDY:   
165                 default:
166                         (void) sprintf(buf, "%d%s%.2d", m, str, d);
167                         break;
168                 case ORDER_DMY:     
169                         (void) sprintf(buf, "%.2d%s%d", d, str, m);
170                         break;
171         }
172 }
173
174 /*
175  *  Format 1 line of appt data.  Returns True if begin hour is < 10 - thus
176  *  padding needs to be done.
177  */
178 extern Boolean
179 format_line(Tick tick,
180     char *what, 
181     char *buf, 
182     int end_tick, 
183     Boolean showtime,
184     DisplayType display)
185 {
186         int hr, hr1, mn, mn1;
187         Boolean am=True;
188         Boolean am_end=True;
189         struct tm *tm;
190         Boolean pad = FALSE;
191         _Xltimeparams localtime_buf;
192
193         if (buf==NULL) return pad;
194         buf[0]=NULL;
195         tm = _XLocaltime(&tick, localtime_buf);
196         hr = tm->tm_hour;
197         mn = tm->tm_min;
198         if (showtime && !magic_time(tick)) {
199                 if (display == HOUR12)
200                         am = adjust_hour(&hr);
201                 if (end_tick && end_tick != tick) {
202                         hr1 = hour(end_tick);
203                         mn1 = minute(end_tick);
204                         if (display == HOUR12) {
205                                 am_end = adjust_hour(&hr1);
206                                 if (am_end != am) {
207                                         (void) sprintf(buf, "%d:%.2d - %d:%.2d%s ", 
208                                                         hr, mn,
209                                                         hr1, mn1, am_end ? "am" : "pm");
210                                 } else {
211                                         (void) sprintf(buf, "%d:%.2d - %d:%.2d ", 
212                                                         hr, mn, hr1, mn1);
213                                 }
214                                 if (hr < 10) pad = TRUE;
215                         }
216                         else
217                                 (void) sprintf(buf, "%02d%02d - %02d%02d ", 
218                                                 hr, mn, hr1, mn1);
219                 }
220                 else {
221                         /* Check to see if there are 2 digits in
222                         in initial time format. If so, pad with
223                         1 space; if not 2.  The font is not fixed
224                         width, so I have to line it up myself.. */
225                         if (display == HOUR12) {
226                                 if (hr > 9)
227                                         (char *)sprintf(buf, "%2d:%.2d%s ", 
228                                                         hr, mn, am ? "a" : "p");
229                                 else {
230                                         (char *)sprintf(buf, "%d:%.2d%s ", 
231                                                         hr, mn, am ? "a" : "p");
232                                         pad = TRUE;
233                                 }
234                         }
235                         else
236                                  (char *)sprintf(buf, "%02d%02d ", hr, mn);
237                 }
238         }
239         if (what)
240                 (void) cm_strcat(buf, what);
241
242         return pad;
243 }
244
245 /*
246  *  Format 2 lines of appt data
247  */
248 extern void
249 format_maxchars(Dtcm_appointment *appt, char *buf1, int maxchars,
250                 DisplayType display) {
251         Tick    tick, end_tick = 0;
252         int     hour1, min1, hour2, min2;
253         Lines   *lines;
254         char    *s1, *s2;
255         struct tm *tm;
256         _Xltimeparams localtime_buf;
257  
258         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
259         if (appt->end_time)
260                 _csa_iso8601_to_tick(appt->end_time->value->item.string_value,
261                         &end_tick);
262         *buf1 = NULL;
263         if (appt == NULL || appt->what->value->item.string_value == NULL) return;
264         tm = _XLocaltime(&tick, localtime_buf);
265         hour1 = tm->tm_hour;
266         min1  = tm->tm_min;
267         if (showtime_set(appt) && !magic_time(tick)) {
268                 s1 = s2 = "am";
269                 if (display == HOUR12 && !adjust_hour(&hour1))
270                         s1="pm";
271
272                 if (end_tick) {
273                         hour2 = hour(end_tick);
274                         if (display == HOUR12 && !adjust_hour(&hour2))
275                                 s2="pm";
276          
277                         min2 = minute(end_tick);
278                 }
279
280                 if (end_tick == 0 || hour1 == hour2 && min1 == min2) {
281                         if (display == HOUR24) 
282                                 sprintf(buf1, "%02d%02d  ", hour1, min1);
283                         else
284                                 sprintf(buf1, "%d:%.2d%s  ", hour1, min1, s1);
285                 }
286                 else {
287                         if (display == HOUR12)
288                                 sprintf(buf1, "%d:%.2d%s-%d:%.2d%s  ", 
289                                         hour1, min1, s1, hour2, min2, s2);
290                         else
291                                 sprintf(buf1, "%02d%02d-%02d%02d  ", 
292                                         hour1, min1, hour2, min2);
293                 }
294         }
295  
296         lines = (Lines *) text_to_lines(appt->what->value->item.string_value, 10);
297  
298         while (lines != NULL) {
299                 if ((cm_strlen(buf1) + cm_strlen(lines->s)) < (maxchars-2)) {
300                         cm_strcat(buf1, lines->s);
301                         lines = lines->next;
302                         if (lines != NULL) 
303                                 cm_strcat(buf1, " - ");
304                 }
305                 else {
306                         strncat(buf1, lines->s, (maxchars - cm_strlen(buf1)-1));
307                         break;
308                 }
309         }
310         destroy_lines(lines);
311 }
312
313
314 /*
315  *  Format 2 lines of appt data
316  */
317 extern void
318 format_line2(Dtcm_appointment *appt, char *buf1, char *buf2,
319              DisplayType display) {
320         Tick    tick, end_tick = 0;
321         int     hour1, min1, hour2, min2;
322         Lines   *lines;
323         char    *s1, *s2;
324         struct tm *tm;
325         _Xltimeparams localtime_buf;
326
327         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);      
328         if (appt->end_time)
329                 _csa_iso8601_to_tick(appt->end_time->value->item.string_value,
330                         &end_tick);     
331  
332         /*
333          * Extract an appointment and format it into 2 lines of no more
334          * then maxchars
335          */
336         *buf1 = *buf2 = NULL;
337         if (appt == NULL || appt->what->value->item.string_value == NULL) return;
338         tm = _XLocaltime(&tick, localtime_buf);
339         hour1 = tm->tm_hour;
340         min1  = tm->tm_min;
341  
342         if (!showtime_set(appt) || magic_time(tick)) {
343                 lines = (Lines *) text_to_lines(appt->what->value->item.string_value, 1);           
344                 if (lines==NULL) return;
345                 strncpy(buf2, lines->s, 256);
346                 destroy_lines(lines);
347                 return;
348         }
349  
350         s1 = s2 = "am";
351         if (display == HOUR12 && !adjust_hour(&hour1))
352                 s1="pm";
353
354         if (end_tick) {
355                 hour2 = hour(end_tick);
356                 min2 = minute(end_tick);
357                 if (display == HOUR12 && !adjust_hour(&hour2))
358                         s2="pm";
359         }
360
361         if (end_tick == 0 ||
362             (hour1 == hour2 && min1 == min2 && (strcmp(s1, s2) == 0))) {
363                 if (display == HOUR24)
364                         sprintf(buf1, "%02d%.2d", hour1, min1);
365                 else
366                         sprintf(buf1, "%d:%.2d%s", hour1, min1, s1);
367         }
368         else {
369                 if (display == HOUR12)
370                         sprintf(buf1, "%d:%.2d%s-%d:%.2d%s", hour1, min1, s1,
371                                  hour2, min2, s2);
372                 else
373                         sprintf(buf1, "%02d%02d-%02d%02d", hour1, min1,
374                                  hour2, min2);
375         }
376
377           
378         lines = (Lines *) text_to_lines(appt->what->value->item.string_value, 1);
379          
380         if (lines == NULL || lines->s == NULL ||                        
381                 (cm_strlen(lines->s) == 1 && lines->s[0] == ' '))
382                 buf2[0] = NULL;
383         else
384                 sprintf(buf2, " %s", lines->s);
385         destroy_lines(lines);
386 }
387
388
389 extern void
390 format_abbrev_appt(Dtcm_appointment *appt, char *b, Boolean show_am,
391                    DisplayType display)
392 {
393         int hr, mn;
394         Tick tick;
395         Lines *lines=NULL;
396         Boolean am = True;
397         struct tm *tm;
398         _Xltimeparams localtime_buf;
399  
400         if(appt==NULL || b==NULL) return;
401         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
402         tm = _XLocaltime(&tick, localtime_buf);
403         hr = tm->tm_hour;
404         mn = tm->tm_min;
405         if (showtime_set(appt) && !magic_time(tick)) {
406                 if (display == HOUR12) {
407                         am = adjust_hour(&hr);
408                         if (show_am)
409                                 sprintf(b, "%2d:%02d%s ", hr, mn, am ? 
410                                                 "a" : "p");
411                         else
412                                 sprintf(b, "%2d:%02d ", hr, mn);
413                 }
414                 else
415                         sprintf(b, "%02d%02d ", hr, mn);
416         }
417         lines = text_to_lines(appt->what->value->item.string_value, 1);
418         if (lines != NULL && lines->s != NULL) {
419                 (void) cm_strcat(b, lines->s);
420                 destroy_lines(lines);
421         }
422 }
423
424 /*
425  *  Format the appointment in the character array passed (assumed to be pointing
426  *  to allocated space) to contain the time followed by the what string.  The
427  *  appointment string is truncated at "max" chars or at DEFAULT_APPT_LEN if
428  *  max is 0.
429  */
430 extern void
431 format_appt(Dtcm_appointment *appt, char *b, DisplayType display, int max) {
432         int             hr, mn, len, i = 0, j = 0;
433         Tick            tick;
434         struct tm       *tm;
435         register char           *what_ptr;
436         _Xltimeparams localtime_buf;
437  
438         if (!appt || !b)
439                 return;
440
441         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
442         tm = _XLocaltime(&tick, localtime_buf);
443         hr = tm->tm_hour;
444         mn = tm->tm_min;
445
446         if (showtime_set(appt) && !magic_time(tick)) {
447                 if (display == HOUR12) {
448                         adjust_hour(&hr);
449                         sprintf(b, "%2d:%02d ", hr, mn);
450                 } else
451                         sprintf(b, "%02d%02d ", hr, mn);
452                 i = cm_strlen(b);
453         }
454
455         if (appt->what->value->item.string_value) {
456                 if (max <= 0)
457                         max = DEFAULT_APPT_LEN;
458                 len = max - i;
459                 what_ptr = appt->what->value->item.string_value;
460                 while ((i < len) && *what_ptr != '\n' && *what_ptr)
461                         b[i++] = *what_ptr++;
462                 b[i] = '\0';
463         }
464 }
465
466 /*
467  *  Format the appointment in the character array passed (assumed to be pointing
468  *  to allocated space) to contain the formatted string for the group
469  *  appointment editor.  The string is truncated at "max" chars or at
470  *  DEFAULT_GAPPT_LEN if max is 0.
471  */
472 extern void
473 format_gappt(Dtcm_appointment *appt, char *name, char *b, DisplayType display,
474             int max) {
475         int             hr, mn, i, j;
476         Tick            tick;
477         char            *what_ptr;
478         struct tm       *tm;
479         _Xltimeparams localtime_buf;
480  
481         if (!appt || !b)
482                 return;
483
484         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
485         if ((tick > 0) && !magic_time(tick) &&
486             showtime_set(appt)) {
487                 tm = _XLocaltime(&tick, localtime_buf);
488                 hr = tm->tm_hour;
489                 mn = tm->tm_min;
490
491                 if (display == HOUR12) {
492                         adjust_hour(&hr);
493                         sprintf(b, "%2d:%02d ", hr, mn);
494                 } else
495                         sprintf(b, "%02d%02d  ", hr, mn);
496         } else
497                 sprintf(b, "%6s", " ");
498
499         if (max <= 0)
500                 max = DEFAULT_GAPPT_LEN;
501         i = cm_strlen(b);
502
503         j = 0;
504         while (j < 10 && i < max && name && name[j])
505                 b[i++] = name[j++];
506         while (j < 11 && i < max)
507                 b[i++] = ' ', ++j;
508
509         if (i >= max) {
510                 b[i - 1] = '\0';
511                 return;
512         }
513         b[i] = '\0';
514
515         if (appt->what->value->item.string_value) {
516                 what_ptr = appt->what->value->item.string_value;
517                 while (i < max && *what_ptr != '\n' && *what_ptr)
518                         b[i++] = *what_ptr++;
519                 b[i] = '\0';
520         }
521 }