dtcm: Resolve CID 87562
[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 #if defined(linux)
73 #undef SVR4
74 #endif
75 #include <X11/Xos_r.h>
76
77 /*
78  *  Convert tick to m, d, y string.  e.g. May 1, 1988
79  */
80 extern void
81 format_date(Tick t, OrderingType order, char *buf, int day_and_date,
82         int and_date, int full_day)
83 {
84         int m, d, y, wd;
85         struct tm *tm;
86         _Xltimeparams localtime_buf;
87
88         buf[0] = '\0';
89         tm = _XLocaltime(&t, localtime_buf);
90         m = tm->tm_mon+1;
91         d = tm->tm_mday;
92         y = tm->tm_year + 1900;
93         wd = tm->tm_wday;
94
95         switch(order) {
96                 case ORDER_DMY:     
97                         /* STRING_EXTRACTION SUNW_DESKSET_CM_MSG :
98                          *
99                          * %s, %d %s %4d is a form of the date format. 
100                          * Change this to reflect your local convention.
101                          * eg. In the German locale, "%s, %d %s %4d" may be changed
102                          * to "%s. %d %s %4d".
103                          */
104                         if (day_and_date)
105                                 if (full_day)
106                                         (void)sprintf(buf, "%s, %d %s %4d", 
107                                                 days2[wd], d, months[m], y);
108                                 else
109                                         (void)sprintf(buf, "%s, %d %s %4d", 
110                                                 days[wd], d, months[m], y);
111                         else if (and_date)
112                                 (void)sprintf(buf, "%d %s %4d", d, months[m], y);
113
114                         else 
115                                 (void) sprintf(buf, "%s %4d", months[m], y);
116                         break;
117                 case ORDER_YMD:    
118                         if (day_and_date) 
119                                 if (full_day)
120                                         (void)sprintf(buf, "%s, %4d %s %d", 
121                                                 days2[wd], y, months[m], d);
122                                 else
123                                         (void)sprintf(buf, "%s, %4d %s %d", 
124                                                 days[wd], y, months[m], d);
125                         else if (and_date)
126                                 (void)sprintf(buf, "%4d %s %d", y, months[m], d);
127                         else 
128                                 (void) sprintf(buf, "%4d %s", y, months[m]);
129                         break;
130                 case ORDER_MDY:   
131                 default:
132                         if (day_and_date) 
133                                 if (full_day)
134                                         (void)sprintf(buf, "%s, %s %d %4d", 
135                                                 days2[wd], months[m], d, y);
136                                 else
137                                         (void)sprintf(buf, "%s, %s %d %4d", 
138                                                 days[wd], months[m], d, y);
139                         else if (and_date)
140                                         (void)sprintf(buf, "%s %d %4d", 
141                                                 months[m], d, y);
142                         else 
143                                 (void) sprintf(buf, "%s %4d", months[m], y);
144                         break;
145         }
146
147 }
148
149 /*
150  *  Convert tick to m/d
151  */
152 extern void
153 format_date3(Tick t, OrderingType order, SeparatorType sep, char *buf) 
154 {
155         int m, d;
156         struct tm *tm;  
157         char *str = (char *) separator_str(sep);
158         _Xltimeparams localtime_buf;
159
160         buf[0] = '\0';
161         tm = _XLocaltime(&t, localtime_buf); 
162
163         m = tm->tm_mon+1; 
164         d = tm->tm_mday;
165         switch(order) {
166                 case ORDER_YMD:    
167                 case ORDER_MDY:   
168                 default:
169                         (void) sprintf(buf, "%d%s%.2d", m, str, d);
170                         break;
171                 case ORDER_DMY:     
172                         (void) sprintf(buf, "%.2d%s%d", d, str, m);
173                         break;
174         }
175 }
176
177 /*
178  *  Format 1 line of appt data.  Returns True if begin hour is < 10 - thus
179  *  padding needs to be done.
180  */
181 extern Boolean
182 format_line(Tick tick,
183     char *what, 
184     char *buf, 
185     int end_tick, 
186     Boolean showtime,
187     DisplayType display)
188 {
189         int hr, hr1, mn, mn1;
190         Boolean am=True;
191         Boolean am_end=True;
192         struct tm *tm;
193         Boolean pad = FALSE;
194         _Xltimeparams localtime_buf;
195
196         if (buf==NULL) return pad;
197         buf[0] = '\0';
198         tm = _XLocaltime(&tick, localtime_buf);
199         hr = tm->tm_hour;
200         mn = tm->tm_min;
201         if (showtime && !magic_time(tick)) {
202                 if (display == HOUR12)
203                         am = adjust_hour(&hr);
204                 if (end_tick && end_tick != tick) {
205                         hr1 = hour(end_tick);
206                         mn1 = minute(end_tick);
207                         if (display == HOUR12) {
208                                 am_end = adjust_hour(&hr1);
209                                 if (am_end != am) {
210                                         (void) sprintf(buf, "%d:%.2d - %d:%.2d%s ", 
211                                                         hr, mn,
212                                                         hr1, mn1, am_end ? "am" : "pm");
213                                 } else {
214                                         (void) sprintf(buf, "%d:%.2d - %d:%.2d ", 
215                                                         hr, mn, hr1, mn1);
216                                 }
217                                 if (hr < 10) pad = TRUE;
218                         }
219                         else
220                                 (void) sprintf(buf, "%02d%02d - %02d%02d ", 
221                                                 hr, mn, hr1, mn1);
222                 }
223                 else {
224                         /* Check to see if there are 2 digits in
225                         in initial time format. If so, pad with
226                         1 space; if not 2.  The font is not fixed
227                         width, so I have to line it up myself.. */
228                         if (display == HOUR12) {
229                                 if (hr > 9)
230                                         sprintf(buf, "%2d:%.2d%s ", 
231                                                         hr, mn, am ? "a" : "p");
232                                 else {
233                                         sprintf(buf, "%d:%.2d%s ", 
234                                                         hr, mn, am ? "a" : "p");
235                                         pad = TRUE;
236                                 }
237                         }
238                         else
239                                  sprintf(buf, "%02d%02d ", hr, mn);
240                 }
241         }
242         if (what)
243                 (void) cm_strcat(buf, what);
244
245         return pad;
246 }
247
248 /*
249  *  Format 2 lines of appt data
250  */
251 extern void
252 format_maxchars(Dtcm_appointment *appt, char *buf1, int maxchars,
253                 DisplayType display) {
254         Tick    tick, end_tick = 0;
255         int     hour1, min1, hour2, min2;
256         Lines   *lines;
257         char    *s1, *s2;
258         struct tm *tm;
259         _Xltimeparams localtime_buf;
260  
261         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
262         if (appt->end_time)
263                 _csa_iso8601_to_tick(appt->end_time->value->item.string_value,
264                         &end_tick);
265         *buf1 = '\0';
266         if (appt == NULL || appt->what->value->item.string_value == NULL) return;
267         tm = _XLocaltime(&tick, localtime_buf);
268         hour1 = tm->tm_hour;
269         min1  = tm->tm_min;
270         if (showtime_set(appt) && !magic_time(tick)) {
271                 s1 = s2 = "am";
272                 if (display == HOUR12 && !adjust_hour(&hour1))
273                         s1="pm";
274
275                 if (end_tick) {
276                         hour2 = hour(end_tick);
277                         if (display == HOUR12 && !adjust_hour(&hour2))
278                                 s2="pm";
279          
280                         min2 = minute(end_tick);
281                 }
282
283                 if (end_tick == 0 || hour1 == hour2 && min1 == min2) {
284                         if (display == HOUR24) 
285                                 sprintf(buf1, "%02d%02d  ", hour1, min1);
286                         else
287                                 sprintf(buf1, "%d:%.2d%s  ", hour1, min1, s1);
288                 }
289                 else {
290                         if (display == HOUR12)
291                                 sprintf(buf1, "%d:%.2d%s-%d:%.2d%s  ", 
292                                         hour1, min1, s1, hour2, min2, s2);
293                         else
294                                 sprintf(buf1, "%02d%02d-%02d%02d  ", 
295                                         hour1, min1, hour2, min2);
296                 }
297         }
298  
299         lines = (Lines *) text_to_lines(appt->what->value->item.string_value, 10);
300  
301         while (lines != NULL) {
302                 if ((cm_strlen(buf1) + cm_strlen(lines->s)) < (maxchars-2)) {
303                         cm_strcat(buf1, lines->s);
304                         lines = lines->next;
305                         if (lines != NULL) 
306                                 cm_strcat(buf1, " - ");
307                 }
308                 else {
309                         strncat(buf1, lines->s, (maxchars - cm_strlen(buf1)-1));
310                         break;
311                 }
312         }
313         destroy_lines(lines);
314 }
315
316
317 /*
318  *  Format 2 lines of appt data
319  */
320 extern void
321 format_line2(Dtcm_appointment *appt, char *buf1, char *buf2,
322              DisplayType display) {
323         Tick    tick, end_tick = 0;
324         int     hour1, min1, hour2, min2;
325         Lines   *lines;
326         char    *s1, *s2;
327         struct tm *tm;
328         _Xltimeparams localtime_buf;
329
330         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);      
331         if (appt->end_time)
332                 _csa_iso8601_to_tick(appt->end_time->value->item.string_value,
333                         &end_tick);     
334  
335         /*
336          * Extract an appointment and format it into 2 lines of no more
337          * then maxchars
338          */
339         *buf1 = *buf2 = '\0';
340         if (appt == NULL || appt->what->value->item.string_value == NULL) return;
341         tm = _XLocaltime(&tick, localtime_buf);
342         hour1 = tm->tm_hour;
343         min1  = tm->tm_min;
344  
345         if (!showtime_set(appt) || magic_time(tick)) {
346                 lines = (Lines *) text_to_lines(appt->what->value->item.string_value, 1);           
347                 if (lines==NULL) return;
348                 strncpy(buf2, lines->s, 256);
349                 destroy_lines(lines);
350                 return;
351         }
352  
353         s1 = s2 = "am";
354         if (display == HOUR12 && !adjust_hour(&hour1))
355                 s1="pm";
356
357         if (end_tick) {
358                 hour2 = hour(end_tick);
359                 min2 = minute(end_tick);
360                 if (display == HOUR12 && !adjust_hour(&hour2))
361                         s2="pm";
362         }
363
364         if (end_tick == 0 ||
365             (hour1 == hour2 && min1 == min2 && (strcmp(s1, s2) == 0))) {
366                 if (display == HOUR24)
367                         sprintf(buf1, "%02d%.2d", hour1, min1);
368                 else
369                         sprintf(buf1, "%d:%.2d%s", hour1, min1, s1);
370         }
371         else {
372                 if (display == HOUR12)
373                         sprintf(buf1, "%d:%.2d%s-%d:%.2d%s", hour1, min1, s1,
374                                  hour2, min2, s2);
375                 else
376                         sprintf(buf1, "%02d%02d-%02d%02d", hour1, min1,
377                                  hour2, min2);
378         }
379
380           
381         lines = (Lines *) text_to_lines(appt->what->value->item.string_value, 1);
382          
383         if (lines == NULL || lines->s == NULL ||                        
384                 (cm_strlen(lines->s) == 1 && lines->s[0] == ' '))
385                 buf2[0] = '\0';
386         else
387                 sprintf(buf2, " %s", lines->s);
388         destroy_lines(lines);
389 }
390
391
392 extern void
393 format_abbrev_appt(Dtcm_appointment *appt, char *b, Boolean show_am,
394                    DisplayType display)
395 {
396         int hr, mn;
397         Tick tick;
398         Lines *lines=NULL;
399         Boolean am = True;
400         struct tm *tm;
401         _Xltimeparams localtime_buf;
402  
403         if(appt==NULL || b==NULL) return;
404         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
405         tm = _XLocaltime(&tick, localtime_buf);
406         hr = tm->tm_hour;
407         mn = tm->tm_min;
408         if (showtime_set(appt) && !magic_time(tick)) {
409                 if (display == HOUR12) {
410                         am = adjust_hour(&hr);
411                         if (show_am)
412                                 sprintf(b, "%2d:%02d%s ", hr, mn, am ? 
413                                                 "a" : "p");
414                         else
415                                 sprintf(b, "%2d:%02d ", hr, mn);
416                 }
417                 else
418                         sprintf(b, "%02d%02d ", hr, mn);
419         }
420         lines = text_to_lines(appt->what->value->item.string_value, 1);
421         if (lines != NULL && lines->s != NULL) {
422                 (void) cm_strcat(b, lines->s);
423                 destroy_lines(lines);
424         }
425 }
426
427 /*
428  *  Format the appointment in the character array passed (assumed to be pointing
429  *  to allocated space) to contain the time followed by the what string.  The
430  *  appointment string is truncated at "max" chars or at DEFAULT_APPT_LEN if
431  *  max is 0.
432  */
433 extern void
434 format_appt(Dtcm_appointment *appt, char *b, DisplayType display, int max) {
435         int             hr, mn, len, i = 0, j = 0;
436         Tick            tick;
437         struct tm       *tm;
438         register char           *what_ptr;
439         _Xltimeparams localtime_buf;
440  
441         if (!appt || !b)
442                 return;
443
444         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
445         tm = _XLocaltime(&tick, localtime_buf);
446         hr = tm->tm_hour;
447         mn = tm->tm_min;
448
449         if (showtime_set(appt) && !magic_time(tick)) {
450                 if (display == HOUR12) {
451                         adjust_hour(&hr);
452                         sprintf(b, "%2d:%02d ", hr, mn);
453                 } else
454                         sprintf(b, "%02d%02d ", hr, mn);
455                 i = cm_strlen(b);
456         }
457
458         if (appt->what->value->item.string_value) {
459                 if (max <= 0)
460                         max = DEFAULT_APPT_LEN;
461                 len = max - i;
462                 what_ptr = appt->what->value->item.string_value;
463                 while ((i < len) && *what_ptr != '\n' && *what_ptr)
464                         b[i++] = *what_ptr++;
465                 b[i] = '\0';
466         }
467 }
468
469 /*
470  *  Format the appointment in the character array passed (assumed to be pointing
471  *  to allocated space) to contain the formatted string for the group
472  *  appointment editor.  The string is truncated at "max" chars or at
473  *  DEFAULT_GAPPT_LEN if max is 0.
474  */
475 extern void
476 format_gappt(Dtcm_appointment *appt, char *name, char *b, DisplayType display,
477             int max) {
478         int             hr, mn, i, j;
479         Tick            tick;
480         char            *what_ptr;
481         struct tm       *tm;
482         _Xltimeparams localtime_buf;
483  
484         if (!appt || !b)
485                 return;
486
487         _csa_iso8601_to_tick(appt->time->value->item.string_value, &tick);
488         if ((tick > 0) && !magic_time(tick) &&
489             showtime_set(appt)) {
490                 tm = _XLocaltime(&tick, localtime_buf);
491                 hr = tm->tm_hour;
492                 mn = tm->tm_min;
493
494                 if (display == HOUR12) {
495                         adjust_hour(&hr);
496                         sprintf(b, "%2d:%02d ", hr, mn);
497                 } else
498                         sprintf(b, "%02d%02d  ", hr, mn);
499         } else
500                 sprintf(b, "%6s", " ");
501
502         if (max <= 0)
503                 max = DEFAULT_GAPPT_LEN;
504         i = cm_strlen(b);
505
506         j = 0;
507         while (j < 10 && i < max && name && name[j])
508                 b[i++] = name[j++];
509         while (j < 11 && i < max)
510                 b[i++] = ' ', ++j;
511
512         if (i >= max) {
513                 b[i - 1] = '\0';
514                 return;
515         }
516         b[i] = '\0';
517
518         if (appt->what->value->item.string_value) {
519                 what_ptr = appt->what->value->item.string_value;
520                 while (i < max && *what_ptr != '\n' && *what_ptr)
521                         b[i++] = *what_ptr++;
522                 b[i] = '\0';
523         }
524 }