1 /*----------------------------------------------------------------------------
2 --
3 --  Module:           xtmBaseCal
4 --
5 --  Project:          Xdiary
6 --  System:           xtm - X Desktop Calendar
7 --    Subsystem:      <>
8 --    Function block: <>
9 --
10 --  Description:
11 --    Display a basic calendar.
12 --
13 --  Filename:         xtmBaseCal.c
14 --
15 --  Authors:          Roger Larsson, Ulrika Bornetun
16 --  Creation date:    1993-07-01
17 --
18 --
19 --  (C) Copyright Ulrika Bornetun, Roger Larsson (1995)
20 --      All rights reserved
21 --
22 --  Permission to use, copy, modify, and distribute this software and its
23 --  documentation for any purpose and without fee is hereby granted,
24 --  provided that the above copyright notice appear in all copies. Ulrika
25 --  Bornetun and Roger Larsson make no representations about the usability
26 --  of this software for any purpose. It is provided "as is" without express
27 --  or implied warranty.
28 ----------------------------------------------------------------------------*/
29 
30 /* SCCS module identifier. */
31 static char SCCSID[] = "@(#) Module: xtmBaseCal.c, Version: 1.1, Date: 95/02/18 15:51:56";
32 
33 
34 /*----------------------------------------------------------------------------
35 --  Include files
36 ----------------------------------------------------------------------------*/
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <assert.h>
42 
43 #include <X11/Intrinsic.h>
44 
45 #include <Xm/Xm.h>
46 #include <Xm/ArrowB.h>
47 #include <Xm/Form.h>
48 #include <Xm/RowColumn.h>
49 
50 #include "System.h"
51 #include "Message.h"
52 #include "TimDate.h"
53 
54 #include "msgXdiary.h"
55 #include "xtmGlobal.h"
56 #include "xtmDbTools.h"
57 #include "xtmIcons.h"
58 #include "xtmFormat.h"
59 #include "xtmHoliday.h"
60 #include "xitError.h"
61 #include "xitTools.h"
62 #include "XmUbMonthD.h"
63 #include "XmUbNoteBk.h"
64 
65 #include "xtmBaseCal.h"
66 
67 
68 /*----------------------------------------------------------------------------
69 --  Macro definitions
70 ----------------------------------------------------------------------------*/
71 
72 /* How many year tabs do we have? */
73 #define  NO_OF_YEAR_TABS      6
74 
75 /* Different style for buttons in calenadr. */
76 #define  STYLE_LABEL_MARK     1
77 #define  STYLE_COLOR_SHADOW   2
78 #define  STYLE_MOTIF_SHADOW   3
79 
80 /* Local widgets in the calendar window. */
81 #define nextYearAb          notebookW[  0 ]
82 #define prevYearAb          notebookW[  1 ]
83 
84 #define calFo               dataLocalW[  0 ]
85 #define calMd               dataLocalW[  1 ]
86 #define todayDateBu         dataLocalW[  2 ]
87 
88 
89 /*----------------------------------------------------------------------------
90 --  Type declarations
91 ----------------------------------------------------------------------------*/
92 
93 typedef enum { YEAR_PREV, YEAR_NEXT } YEAR_DIRECTION;
94 
95 /* Data for the calendar. */
96 typedef struct {
97   Boolean                entry_defined[ 6 * 7 ];
98   Boolean                first_time;
99   int                    curr_year;
100   int                    curr_month;
101   int                    first_year_tab;
102   int                    last_year_tab;
103   Widget                 calendarW;
104   Widget                 workAreaW;
105   TIM_TIME_REF           this_date;
106   XTM_BC_CAL_STYLE       style;
107   XTM_GL_BASE_DATA_REF   appl_data_ref;
108   XTM_BC_ACTION_CB       actionCB;
109   XTM_BC_HAS_ENTRIES_CB  hasEntriesCB;
110   void                   *user_data;
111 } CAL_REC, *CAL_REC_REF;
112 
113 
114 /* Data for year scroll buttons. */
115 typedef struct {
116   YEAR_DIRECTION  direction;
117   CAL_REC_REF     cal_ref;
118 } SCROLL_YEAR_REC, *SCROLL_YEAR_REF;
119 
120 
121 /* Data for year select buttons. */
122 typedef struct {
123   int          index;
124   int          year;
125   CAL_REC_REF  cal_ref;
126 } YEAR_REC, *YEAR_REF;
127 
128 
129 /* Data for month select buttons. */
130 typedef struct {
131   int          index;
132   int          month;
133   CAL_REC_REF  cal_ref;
134 } MONTH_REC, *MONTH_REF;
135 
136 /* Data for date buttons. */
137 typedef struct {
138   TIM_TIME_REF  date;
139   CAL_REC_REF   cal_ref;
140 } DATE_REC, *DATE_REF;
141 
142 
143 /*----------------------------------------------------------------------------
144 --  Global definitions
145 ----------------------------------------------------------------------------*/
146 
147 /* Name of module. */
148 static char  *module_name = "xtmBaseCalendar";
149 
150 /* Pixmaps to use for binding. */
151 static Pixmap  top_pixmap       = None;
152 static Pixmap  left_top_pixmap  = None;
153 static Pixmap  right_top_pixmap = None;
154 
155 
156 /*----------------------------------------------------------------------------
157 --  Function prototypes
158 ----------------------------------------------------------------------------*/
159 
160 static Widget
161   createCalendarWindow( CAL_REC_REF  cal_ref,
162                         Widget       parentW );
163 
164 static void
165   dateSelectCB( Widget                          widget,
166                 CAL_REC_REF                     cal_ref,
167                 XmUbMonthDisplayCallbackStruct  *call_data );
168 
169 static void
170   destroyTabCB( Widget     widget,
171                 XtPointer  user_data_ref,
172                 XtPointer  call_data );
173 
174 static void
175   displayMonth( CAL_REC_REF   cal_ref,
176                 TIM_TIME_REF  cal_date );
177 
178 static void
179   displayTimeLabel( CAL_REC_REF  cal_ref );
180 
181 static void
182   messageCB( Widget       widget,
183              CAL_REC_REF  cal_ref,
184              XtPointer    call_data );
185 
186 static void
187   monthSelectCB( Widget     widget,
188                  MONTH_REF  month_ref,
189                  XtPointer  call_data );
190 
191 static void
192   scrollYearCB( Widget           widget,
193                 SCROLL_YEAR_REF  scroll_ref,
194                 XtPointer        call_data );
195 
196 static void
197   setYearTabs( CAL_REC_REF  cal_ref,
198                int          start_on_year );
199 
200 static void
201   todayCB( Widget       widget,
202            CAL_REC_REF  cal_ref,
203            XtPointer    call_data );
204 
205 static void
206   updateMonthCB( Widget                          widget,
207                  CAL_REC_REF                     cal_ref,
208                  XmUbMdiUpdateDayCallbackStruct  *call_data );
209 
210 static void
211   yearSelectCB( Widget     widget,
212                 YEAR_REF   year_ref,
213                 XtPointer  call_data );
214 
215 
216 
217 /*----------------------------------------------------------------------------
218 --  Functions
219 ----------------------------------------------------------------------------*/
220 
221 XTM_BC_HANDLE
xtmBcInitialize(XTM_GL_BASE_DATA_REF appl_data_ref,Widget parentW,XTM_BC_CAL_STYLE style,XTM_BC_ACTION_CB actionCB,XTM_BC_HAS_ENTRIES_CB hasEntriesCB,void * user_data)222   xtmBcInitialize( XTM_GL_BASE_DATA_REF   appl_data_ref,
223                    Widget                 parentW,
224                    XTM_BC_CAL_STYLE       style,
225                    XTM_BC_ACTION_CB       actionCB,
226                    XTM_BC_HAS_ENTRIES_CB  hasEntriesCB,
227                    void                   *user_data )
228 {
229 
230   /* Variables. */
231   CAL_REC_REF  cal_ref;
232 
233 
234   /* Code. */
235 
236   cal_ref = SysNew( CAL_REC );
237   if( cal_ref == NULL )
238     return( NULL );
239 
240   cal_ref -> appl_data_ref = appl_data_ref;
241   cal_ref -> curr_year     = 1981;
242   cal_ref -> curr_month    = 1;
243   cal_ref -> first_time    = True;
244   cal_ref -> style         = style;
245   cal_ref -> calendarW     = NULL;
246   cal_ref -> actionCB      = actionCB;
247   cal_ref -> hasEntriesCB  = hasEntriesCB;
248   cal_ref -> user_data     = user_data;
249 
250 
251   /* Calendar window. */
252   cal_ref -> calendarW = createCalendarWindow( cal_ref, parentW );
253 
254   if( cal_ref -> calendarW == NULL ) {
255     SysFree( cal_ref );
256     return( NULL );
257   }
258 
259 
260   return( cal_ref );
261 
262 } /* xtmBcInitialize */
263 
264 
265 /*----------------------------------------------------------------------*/
266 
267 void
xtmBcDestroy(XTM_BC_HANDLE cal_handle)268   xtmBcDestroy( XTM_BC_HANDLE  cal_handle )
269 {
270 
271   /* Variables. */
272   CAL_REC_REF  cal_ref;
273 
274 
275   /* Code. */
276 
277   if( cal_handle == NULL )
278     return;
279 
280   /* Our private data. */
281   cal_ref = (CAL_REC_REF) cal_handle;
282 
283   /* Do we have a user action callback registered? */
284   if( cal_ref -> actionCB != NULL )
285     (* cal_ref -> actionCB)( XTM_BC_REASON_DESTROY,
286                              (TIM_TIME_REF) 0, NULL,
287                              cal_ref -> user_data );
288 
289   /* Destroy the widget. */
290   XtDestroyWidget( cal_ref -> calendarW );
291 
292   /* Free allocated data. */
293   SysFree( cal_ref );
294 
295 
296   return;
297 
298 } /* xtmBcDestroy */
299 
300 
301 /*----------------------------------------------------------------------*/
302 
303 void
xtmBcDisplayMonth(XTM_BC_HANDLE cal_handle,TIM_TIME_REF cal_date)304   xtmBcDisplayMonth( XTM_BC_HANDLE  cal_handle,
305                      TIM_TIME_REF   cal_date )
306 {
307 
308   /* Variables. */
309   CAL_REC_REF  cal_ref;
310 
311 
312   /* Code. */
313 
314   if( cal_handle == NULL )
315     return;
316 
317   /* Our private data. */
318   cal_ref = (CAL_REC_REF) cal_handle;
319 
320   /* Display the month. */
321   displayMonth( cal_ref, cal_date );
322 
323 
324   return;
325 
326 } /* xtmBcDisplayMonth */
327 
328 
329 /*----------------------------------------------------------------------*/
330 
331 void
xtmBcDisplayTime(XTM_BC_HANDLE cal_handle)332   xtmBcDisplayTime( XTM_BC_HANDLE  cal_handle )
333 {
334 
335   /* Variables. */
336   CAL_REC_REF  cal_ref;
337 
338 
339   /* Code. */
340 
341   if( cal_handle == NULL )
342     return;
343 
344   /* Our private data. */
345   cal_ref = (CAL_REC_REF) cal_handle;
346 
347   /* Display the current time. */
348   displayTimeLabel( cal_ref );
349 
350 
351   return;
352 
353 } /* xtmBcDisplayTime */
354 
355 
356 /*----------------------------------------------------------------------*/
357 
358 Widget
xtmBcGetWidget(XTM_BC_HANDLE cal_handle)359   xtmBcGetWidget( XTM_BC_HANDLE  cal_handle )
360 {
361 
362   /* Variables. */
363   CAL_REC_REF  cal_ref;
364 
365 
366   /* Code. */
367 
368   if( cal_handle == NULL )
369     return( NULL );
370 
371   /* Our private data. */
372   cal_ref = (CAL_REC_REF) cal_handle;
373 
374 
375   return( cal_ref -> calendarW );
376 
377 } /* xtmBcGetWidget */
378 
379 
380 /*----------------------------------------------------------------------*/
381 
382 void
xtmBcSignalMessage(XTM_BC_HANDLE cal_handle,Boolean has_message)383   xtmBcSignalMessage( XTM_BC_HANDLE  cal_handle,
384                       Boolean        has_message )
385 {
386 
387   /* Variables. */
388   Arg                     args[ 5 ];
389   Cardinal                n;
390   Widget                  msgW;
391   CAL_REC_REF             cal_ref;
392   XTM_GL_CUSTOM_DATA_REF  custom_data_ref;
393 
394   static Pixmap  msg_pixmap = None;
395 
396 
397   /* Code. */
398 
399   if( cal_handle == NULL )
400     return;
401 
402   /* Our private data. */
403   cal_ref = (CAL_REC_REF) cal_handle;
404 
405   custom_data_ref = cal_ref -> appl_data_ref -> custom_data;
406 
407 
408   /* Fetch the pixmap to display. */
409   msgW = XtNameToWidget( cal_ref -> calendarW, "CalFo.MessageBu" );
410 
411   if( msg_pixmap == None ) {
412     msg_pixmap = xtmIcFetchSimplePixmap( msgW, XTM_IC_ICON_MESSAGE, False );
413 
414     n = 0;
415     XtSetArg( args[ n ], XmNlabelPixmap, msg_pixmap ); n++;
416     XtSetValues( msgW, args, n );
417   }
418 
419 
420   /* Display the message icon? */
421   if( has_message ) {
422     XtManageChild( msgW );
423     if( XtIsRealized( msgW ) )
424       XRaiseWindow( XtDisplay( msgW ), XtWindow( msgW ) );
425   } else {
426     XtUnmanageChild( msgW );
427   }
428 
429 
430   if( has_message )
431     XBell( XtDisplay( msgW ), 100 );
432 
433 
434   return;
435 
436 } /* xtmBcSignalMessage */
437 
438 
439 /*----------------------------------------------------------------------*/
440 
441 void
xtmBcViewCalendar(XTM_BC_HANDLE cal_handle)442   xtmBcViewCalendar( XTM_BC_HANDLE  cal_handle )
443 {
444 
445   /* Variables. */
446   CAL_REC_REF  cal_ref;
447 
448 
449   /* Code. */
450 
451   if( cal_handle == NULL )
452     return;
453 
454   /* Our private data. */
455   cal_ref = (CAL_REC_REF) cal_handle;
456 
457   /* Manage the calendar window. */
458   XtManageChild( cal_ref -> calendarW );
459 
460   cal_ref -> first_time = True;
461 
462 
463   return;
464 
465 } /* xtmBcViewCalendar */
466 
467 
468 /*----------------------------------------------------------------------*/
469 
470 static Widget
createCalendarWindow(CAL_REC_REF cal_ref,Widget parentW)471   createCalendarWindow( CAL_REC_REF  cal_ref,
472                         Widget       parentW )
473 {
474 
475   /* Variables. */
476   int                     index;
477   char                    buffer[ 20 ];
478   Arg                     args[ 20 ];
479   Cardinal                n;
480   Widget                  calendarW = 0;
481   Widget                  dataLocalW[ 3 ];
482   Widget                  messageBu;
483   Widget                  month_tab[ 12 ];
484   Widget                  notebookW[ 2 ];
485   Widget                  tempW;
486   Widget                  year_tab[ NO_OF_YEAR_TABS ];
487   XmString                xstr;
488   XmString                xstr1;
489   XmString                xstr2;
490   MONTH_REF               tab_month_ref;
491   SCROLL_YEAR_REF         scroll_year_ref;
492   TIM_TIME_REF            curr_date;
493   XTM_GL_CUSTOM_DATA_REF  custom_data;
494   YEAR_REF                tab_year_ref;
495 
496   static XIT_ARROW_STRUCT scroll_year_button[] = {
497     { "PrevYearAr", True, XmARROW_UP,   NULL },
498     { "NextYearAr", True, XmARROW_DOWN,  NULL },
499   };
500 
501   static XIT_PUSH_STRUCT button_def[] = {
502     { "TodayDateBu", "Date\nTime", "", True, NULL },
503     { "MessageBu",   " ",          "", True, NULL },
504   };
505 
506   static XIT_PUSH_STRUCT tab_button_def[] = {
507     { "", "99", "", True, NULL },
508     { "", "9",  "", True, NULL },
509   };
510 
511 
512   /* Code. */
513 
514   custom_data = cal_ref -> appl_data_ref -> custom_data;
515 
516 
517   /* The calendar is kept within a note book? */
518   if( cal_ref -> style == XTM_BC_STYLE_NOTEBOOK ) {
519 
520     n = 0;
521     calendarW = XmUbCreateNoteBook( parentW, "Calendar", args, n );
522 
523     /* Binding pixmaps? */
524     if( top_pixmap == None )
525       top_pixmap = xtmIcFetchSimplePixmap(
526                      calendarW, XTM_IC_ICON_CAL_TOP, False );
527 
528     if( left_top_pixmap == None )
529       left_top_pixmap = xtmIcFetchSimplePixmap(
530                           calendarW, XTM_IC_ICON_CAL_LEFT_TOP, False );
531 
532     if( right_top_pixmap == None )
533       right_top_pixmap = xtmIcFetchSimplePixmap(
534                            calendarW, XTM_IC_ICON_CAL_RIGHT_TOP, False );
535 
536     n = 0;
537     XtSetArg( args[ n ], XmUbNbindingType, XmUbBINDING_PIXMAP ); n++;
538     XtSetArg( args[ n ], XmUbNbindingPixmapCenter, top_pixmap ); n++;
539     XtSetArg( args[ n ], XmUbNbindingPixmapStart, left_top_pixmap ); n++;
540     XtSetArg( args[ n ], XmUbNbindingPixmapEnd, right_top_pixmap ); n++;
541     XtSetValues( calendarW, args, n );
542 
543 
544     /* Year tabs. */
545     for( index = 0; index < XtNumber( year_tab ); index ++ ) {
546 
547       tab_year_ref = SysNew( YEAR_REC );
548       if( tab_year_ref == NULL )
549         return( NULL );
550 
551       tab_year_ref -> index   = index;
552       tab_year_ref -> year    = 0;
553       tab_year_ref -> cal_ref = cal_ref;
554 
555       sprintf( buffer, "YearTab%dPb", index + 1 );
556 
557       tab_button_def[ 0 ].name = buffer;
558       year_tab[ index ] = xitCreatePushButton( calendarW,
559                                                &tab_button_def[ 0 ] );
560 
561       n = 0;
562       XtSetArg( args[ n ], XmUbNchildType, XmUbTAB ); n++;
563       XtSetArg( args[ n ], XmUbNposition, XmUbRIGHT ); n++;
564       XtSetArg( args[ n ], XmNuserData, (XtPointer) tab_year_ref ); n++;
565       XtSetArg( args[ n ], XmNshadowThickness, 1 ); n++;
566       XtSetArg( args[ n ], XmNrecomputeSize, False ); n++;
567       XtSetValues( year_tab[ index ], args, n );
568 
569       xitStringSetLabel( year_tab[ index ], " " );
570 
571       XtAddCallback( year_tab[ index ], XmNactivateCallback,
572                      (XtCallbackProc) yearSelectCB, (XtPointer) tab_year_ref );
573       XtAddCallback( year_tab[ index ], XmNdestroyCallback,
574                      (XtCallbackProc) destroyTabCB, (XtPointer) tab_year_ref );
575 
576     } /* loop */
577 
578 
579     /* Scroll to previous years. */
580     scroll_year_ref = SysNew( SCROLL_YEAR_REC );
581     if( scroll_year_ref == NULL )
582       return( NULL );
583 
584     scroll_year_ref -> direction = YEAR_PREV;
585     scroll_year_ref -> cal_ref   = cal_ref;
586 
587     prevYearAb = xitCreateArrowPushButton( calendarW,
588                                            &scroll_year_button[ 0 ] );
589 
590     n = 0;
591     XtSetArg( args[ n ], XmUbNchildType, XmUbSCROLL_BUTTON ); n++;
592     XtSetArg( args[ n ], XmUbNscrollDirection, XmUbSCROLL_BACK ); n++;
593     XtSetArg( args[ n ], XmUbNposition, XmUbRIGHT ); n++;
594     XtSetArg( args[ n ], XmNshadowThickness, 1 ); n++;
595     XtSetArg( args[ n ], XmNuserData, (XtPointer) scroll_year_ref ); n++;
596     XtSetValues( prevYearAb, args, n );
597 
598     XtAddCallback( prevYearAb, XmNactivateCallback,
599                    (XtCallbackProc) scrollYearCB,
600                    (XtPointer) scroll_year_ref );
601     XtAddCallback( prevYearAb, XmNdestroyCallback,
602                    (XtCallbackProc) destroyTabCB,
603                    (XtPointer) scroll_year_ref );
604 
605 
606     /* Scroll to next years. */
607     scroll_year_ref = SysNew( SCROLL_YEAR_REC );
608     if( scroll_year_ref == NULL )
609       return( NULL );
610 
611     scroll_year_ref -> direction = YEAR_NEXT;
612     scroll_year_ref -> cal_ref   = cal_ref;
613 
614     nextYearAb = xitCreateArrowPushButton( calendarW,
615                                            &scroll_year_button[ 1 ] );
616 
617     n = 0;
618     XtSetArg( args[ n ], XmUbNchildType, XmUbSCROLL_BUTTON ); n++;
619     XtSetArg( args[ n ], XmUbNscrollDirection, XmUbSCROLL_FORWARD ); n++;
620     XtSetArg( args[ n ], XmUbNposition, XmUbRIGHT ); n++;
621     XtSetArg( args[ n ], XmNshadowThickness, 1 ); n++;
622     XtSetArg( args[ n ], XmNuserData, (XtPointer) scroll_year_ref ); n++;
623     XtSetValues( nextYearAb, args, n );
624 
625     XtAddCallback( nextYearAb, XmNactivateCallback,
626                    (XtCallbackProc) scrollYearCB,
627                    (XtPointer) scroll_year_ref );
628     XtAddCallback( nextYearAb, XmNdestroyCallback,
629                    (XtCallbackProc) destroyTabCB,
630                    (XtPointer) scroll_year_ref );
631 
632 
633     /* Month tabs. */
634     curr_date = TimMakeTime( 1970, 1, 1, 0, 0, 0 );
635 
636     for( index = 0; index < XtNumber( month_tab ); index ++ ) {
637 
638       char  month_name[ 10 ];
639 
640       tab_month_ref = SysNew( MONTH_REC );
641       if( tab_month_ref == NULL )
642         return( NULL );
643 
644       tab_month_ref -> index   = index;
645       tab_month_ref -> month   = index + 1;
646       tab_month_ref -> cal_ref = cal_ref;
647 
648       sprintf( buffer, "MonthTab%dPb", index + 1 );
649 
650       tab_button_def[ 1 ].name = buffer;
651       month_tab[ index ] = xitCreatePushButton( calendarW,
652                                                 &tab_button_def[ 1 ] );
653 
654       n = 0;
655       XtSetArg( args[ n ], XmUbNchildType, XmUbTAB ); n++;
656       XtSetArg( args[ n ], XmUbNposition, XmUbBOTTOM ); n++;
657       XtSetArg( args[ n ], XmNuserData, (XtPointer) tab_month_ref ); n++;
658       XtSetArg( args[ n ], XmNshadowThickness, 1 ); n++;
659       XtSetArg( args[ n ], XmNrecomputeSize, False ); n++;
660       XtSetValues( month_tab[ index ], args, n );
661 
662       XtAddCallback( month_tab[ index ], XmNactivateCallback,
663                      (XtCallbackProc) monthSelectCB,
664                      (XtPointer) tab_month_ref );
665       XtAddCallback( month_tab[ index ], XmNdestroyCallback,
666                      (XtCallbackProc) destroyTabCB,
667                      (XtPointer) tab_month_ref );
668 
669       /* Month name (one character). */
670       TimFormatStrTime( curr_date, "%b", buffer,  sizeof( buffer ) );
671       month_name[ 0 ] = buffer[ 0 ];
672       month_name[ 1 ] = '\0';
673 
674       xitStringSetLabel( month_tab[ index ], month_name );
675       TimAddMonths( &curr_date, 1 );
676 
677     } /* loop */
678 
679 
680     /* Create form to hold calendar. */
681     n = 0;
682     calFo = XmCreateForm( calendarW, "CalFo", args, n );
683     cal_ref -> workAreaW = calFo;
684 
685     n = 0;
686     XtSetArg( args[ n ], XmUbNworkArea, calFo ); n++;
687     XtSetValues( calendarW, args, n );
688 
689   } /* if */
690 
691 
692   /* The calendar is kept within a form? */
693   if( cal_ref -> style == XTM_BC_STYLE_PLAIN ) {
694 
695     n = 0;
696     calendarW = XmCreateForm( parentW, "Calendar", args, n );
697 
698     /* Create form to hold calendar. */
699     n = 0;
700     calFo = XmCreateForm( calendarW, "CalFo", args, n );
701     cal_ref -> workAreaW = calFo;
702 
703   } /* if */
704   assert( calendarW != 0 );
705 
706   /* Create date button. */
707   todayDateBu = xitCreatePushButton(  calFo, &button_def[ 0 ] );
708   XtAddCallback( todayDateBu, XmNactivateCallback,
709                  (XtCallbackProc) todayCB, (XtPointer) cal_ref );
710 
711   n = 0;
712   XtSetArg( args[ n ], XmNshadowThickness, 0 ); n++;
713   XtSetValues( todayDateBu, args, n );
714 
715 
716   /* Create the calendar. */
717   xstr  = XmStringCreateLtoR( msgGetText( MXDI_WEEK_NUMBER_LABEL ), CS );
718   xstr1 = XmStringCreateLtoR( msgGetText( MXDI_MONTH_LABEL ), CS );
719   xstr2 = XmStringCreateLtoR( msgGetText( MXDI_YEAR_LABEL ), CS );
720 
721   n = 0;
722   XtSetArg( args[ n ], XmUbNmdiTitleAlignment, XmALIGNMENT_BEGINNING ); n++;
723   XtSetArg( args[ n ], XmUbNmdiWeekLabel, xstr ); n++;
724   XtSetArg( args[ n ], XmUbNmdiUseDefaultTitleCallback, False ); n++;
725   XtSetArg( args[ n ], XmUbNmdiTitleShadows, False ); n++;
726 
727   if( ! custom_data -> show_week_numbers ) {
728     XtSetArg( args[ n ], XmUbNmdiWeekNumbers, False ); n++;
729   }
730 
731   if( cal_ref -> style == XTM_BC_STYLE_NOTEBOOK ) {
732     XtSetArg( args[ n ], XmUbNmdiMonthArrows, False ); n++;
733     XtSetArg( args[ n ], XmUbNmdiMonthLabel, xstr1 ); n++;
734     XtSetArg( args[ n ], XmUbNmdiYearArrows, False ); n++;
735     XtSetArg( args[ n ], XmUbNmdiYearLabel, xstr2 ); n++;
736   }
737   calMd = XmUbCreateMonthDisplay( calFo, "CalMd", args, n );
738 
739   XmStringFree( xstr );
740   XmStringFree( xstr1 );
741   XmStringFree( xstr2 );
742 
743   XtAddCallback( calMd, XmUbNmdiUpdateDayCallback,
744                  (XtCallbackProc) updateMonthCB, (XtPointer) cal_ref );
745   XtAddCallback( calMd, XmUbNmdiDateSelectedCallback,
746                  (XtCallbackProc) dateSelectCB, (XtPointer) cal_ref );
747 
748 
749   /* Create the message indicator. */
750   messageBu = xitCreatePushButton( calFo, &button_def[ 1 ] );
751 
752   XtAddCallback( messageBu, XmNactivateCallback,
753                  (XtCallbackProc) messageCB, (XtPointer) cal_ref );
754 
755   n = 0;
756   XtSetArg( args[ n ], XmNtraversalOn, False ); n++;
757   XtSetArg( args[ n ], XmNlabelType, XmPIXMAP ); n++;
758   XtSetArg( args[ n ], XmNforeground, custom_data -> entry_exist_fg ); n++;
759   XtSetValues( messageBu, args, n );
760 
761 
762   /* Position the widgets. */
763   xitAttachWidget( todayDateBu,
764                    XmATTACH_FORM, NULL, XmATTACH_FORM, NULL,
765                    XmATTACH_FORM, NULL, XmATTACH_NONE, NULL );
766   xitAttachWidget( messageBu,
767                    XmATTACH_FORM, NULL, XmATTACH_NONE, NULL,
768                    XmATTACH_FORM, NULL, XmATTACH_NONE, NULL );
769   xitAttachWidget( calMd,
770                    XmATTACH_WIDGET, todayDateBu, XmATTACH_FORM, NULL,
771                    XmATTACH_NONE,   NULL,        XmATTACH_NONE, NULL );
772 
773 
774   /* Manage the style widgets. */
775   if( cal_ref -> style == XTM_BC_STYLE_NOTEBOOK ) {
776     xitManageChildren( notebookW, XtNumber( notebookW ) );
777     xitManageChildren( month_tab, XtNumber( month_tab ) );
778     xitManageChildren( year_tab,  XtNumber( year_tab ) );
779   }
780 
781   /* Manage the common widgets. */
782   xitManageChildren( dataLocalW, XtNumber( dataLocalW ) );
783 
784 
785   /* Grab focus. */
786   if( cal_ref -> style == XTM_BC_STYLE_PLAIN ) {
787     tempW = XmUbMonthDisplayGetChild( calMd, XmUbMD_CHILD_MONTH_ARROW );
788 
789     xitSetFocus( calendarW, tempW );
790   }
791 
792 
793   return( calendarW );
794 
795 } /* createCalendarWindow */
796 
797 
798 /*----------------------------------------------------------------------*/
799 
800 static void
displayMonth(CAL_REC_REF cal_ref,TIM_TIME_REF cal_date)801   displayMonth( CAL_REC_REF   cal_ref,
802                 TIM_TIME_REF  cal_date )
803 {
804 
805   /* Variables. */
806   char                    buffer[ 50 ];
807   Arg                     args[ 10 ];
808   Cardinal                n;
809   Widget                  tempW;
810   XTM_GL_CUSTOM_DATA_REF  custom_data_ref;
811 
812 
813   /* Code. */
814 
815   custom_data_ref = cal_ref -> appl_data_ref -> custom_data;
816 
817   /* Keep the year and month. */
818   cal_ref -> curr_year  = TimIndexOfYear(  cal_date );
819   cal_ref -> curr_month = TimIndexOfMonth( cal_date );
820 
821 
822   /* Display the month. */
823   tempW = XtNameToWidget( cal_ref -> workAreaW, "CalMd" );
824 
825   n = 0;
826   XtSetArg( args[ n ], XmUbNmdiFillOutWeek,
827             custom_data_ref -> cal_month_extend ); n++;
828   XtSetValues( tempW, args, n );
829 
830   XmUbMonthDisplaySetMonth( tempW,
831                             cal_ref -> curr_year, cal_ref -> curr_month );
832 
833 
834   /* Set the current time. */
835   displayTimeLabel( cal_ref );
836 
837 
838   /* If this is the first time, display the year labels. */
839   if( cal_ref -> first_time && cal_ref -> style == XTM_BC_STYLE_NOTEBOOK ) {
840     if( cal_ref -> curr_year > 1971 )
841       setYearTabs( cal_ref, cal_ref -> curr_year - 1 );
842     else
843       setYearTabs( cal_ref, cal_ref -> curr_year );
844   }
845 
846   cal_ref -> first_time = False;
847 
848 
849   /* Make sure the year tabs are displayed correctly. */
850   if( cal_ref -> style == XTM_BC_STYLE_NOTEBOOK ) {
851 
852     if( cal_ref -> curr_year >= cal_ref -> first_year_tab &&
853         cal_ref -> curr_year <= cal_ref -> last_year_tab )
854       sprintf( buffer, "YearTab%dPb",
855                cal_ref -> curr_year - cal_ref -> first_year_tab + 1 );
856     else
857       sprintf( buffer, "YearTab%dPb", 1 );
858 
859     tempW = XtNameToWidget( cal_ref -> calendarW, buffer );
860     XmUbNoteBookSelectedTab( cal_ref -> calendarW, tempW, XmUbRIGHT );
861 
862 
863     /* Make sure the month tabs are displayed correctly. */
864     sprintf( buffer, "MonthTab%dPb", cal_ref -> curr_month );
865     tempW = XtNameToWidget( cal_ref -> calendarW, buffer );
866 
867     XmUbNoteBookSelectedTab( cal_ref -> calendarW, tempW, XmUbBOTTOM );
868 
869   } /* if */
870 
871 
872   /* Anyone interested? */
873   if( cal_ref -> actionCB != NULL )
874     (* cal_ref -> actionCB)( XTM_BC_REASON_MONTH_DISPLAYED,
875                              cal_date, NULL,
876                              cal_ref -> user_data );
877 
878 
879   return;
880 
881 } /* displayMonth */
882 
883 
884 /*----------------------------------------------------------------------*/
885 
886 static void
displayTimeLabel(CAL_REC_REF cal_ref)887   displayTimeLabel( CAL_REC_REF  cal_ref )
888 {
889 
890   /* Variables. */
891   char                    buffer[ 40 ];
892   Widget                  todayDateW;
893   XTM_GL_CUSTOM_DATA_REF  custom_data;
894 
895 
896   /* Code. */
897 
898   custom_data = cal_ref -> appl_data_ref -> custom_data;
899 
900 
901   /* Get the widget. */
902   todayDateW = XtNameToWidget( cal_ref -> workAreaW, "TodayDateBu" );
903 
904   xtmFoFormatFullTime( TimLocalTime( TimMakeTimeNow() ),
905                        buffer, sizeof( buffer ) );
906 
907   /* Set the today date label. */
908   xitStringSetLabel( todayDateW, buffer );
909 
910 
911   return;
912 
913 } /* displayTimeLabel */
914 
915 
916 /*----------------------------------------------------------------------*/
917 
918 static void
setYearTabs(CAL_REC_REF cal_ref,int start_on_year)919   setYearTabs( CAL_REC_REF  cal_ref,
920                int          start_on_year )
921 {
922 
923   /* Variables. */
924   int        full_year;
925   int        index;
926   int        year;
927   char       buffer[ 50 ];
928   Arg        args[ 10 ];
929   Cardinal   n;
930   Widget     tempW;
931   XtPointer  user_data_ref;
932   YEAR_REF   tab_year_ref;
933 
934 
935   /* Code. */
936 
937   cal_ref -> first_year_tab = start_on_year;
938   cal_ref -> last_year_tab  = start_on_year + NO_OF_YEAR_TABS - 1;
939 
940   /* Only disply the last two digits. */
941   full_year = start_on_year;
942   year      = start_on_year;
943 
944   while( year > 99 )
945     year = year - 100;
946 
947 
948   /* Set the correct year on the tabs. */
949   for( index = 0; index < NO_OF_YEAR_TABS; index++ ) {
950 
951     sprintf( buffer, "YearTab%dPb", index + 1 );
952     tempW = XtNameToWidget( cal_ref -> calendarW, buffer );
953 
954     n = 0;
955     XtSetArg( args[ n ], XmNuserData, &user_data_ref ); n++;
956     XtGetValues( tempW, args, n );
957 
958     tab_year_ref = (YEAR_REF) user_data_ref;
959 
960     /* Set the year label */
961     sprintf( buffer, "%2.2d", year );
962     xitStringSetLabel( tempW, buffer );
963 
964     /* Save the year for later. */
965     tab_year_ref -> year = full_year;
966 
967     full_year++;
968     year++;
969     if( year > 99 )
970       year = year - 100;
971 
972   } /* loop */
973 
974 
975   return;
976 
977 } /* setYearTabs */
978 
979 
980 /*----------------------------------------------------------------------*/
981 
982 static void
dateSelectCB(Widget widget,CAL_REC_REF cal_ref,XmUbMonthDisplayCallbackStruct * call_data)983   dateSelectCB( Widget                          widget,
984                 CAL_REC_REF                     cal_ref,
985                 XmUbMonthDisplayCallbackStruct  *call_data )
986 {
987 
988   /* Variables. */
989   TIM_TIME_REF  selected_date;
990 
991 
992   /* Code. */
993 
994   if( call_data -> reason != XmUbCR_DATE_SELECTED )
995     return;
996 
997   selected_date = TimMakeTime( call_data -> selected_year,
998                                call_data -> selected_month,
999                                call_data -> selected_day, 0, 0, 0 );
1000 
1001   if( cal_ref -> actionCB != NULL )
1002     (* cal_ref -> actionCB)( XTM_BC_REASON_DATE_SELECTED,
1003                              selected_date,
1004                              (XmAnyCallbackStruct *) call_data,
1005                              cal_ref -> user_data );
1006 
1007 
1008   return;
1009 
1010 } /* dateSelectCB */
1011 
1012 
1013 /*----------------------------------------------------------------------*/
1014 
1015 static void
destroyTabCB(Widget widget,XtPointer user_data_ref,XtPointer call_data)1016   destroyTabCB( Widget     widget,
1017                 XtPointer  user_data_ref,
1018                 XtPointer  call_data )
1019 {
1020 
1021   /* Code. */
1022 
1023   SysFree( user_data_ref );
1024 
1025 
1026   return;
1027 
1028 } /* destroyTabCB */
1029 
1030 
1031 /*----------------------------------------------------------------------*/
1032 
1033 static void
messageCB(Widget widget,CAL_REC_REF cal_ref,XtPointer call_data)1034   messageCB( Widget       widget,
1035              CAL_REC_REF  cal_ref,
1036              XtPointer    call_data )
1037 {
1038 
1039   /* Code. */
1040 
1041   if( cal_ref -> actionCB != NULL )
1042     (* cal_ref -> actionCB)( XTM_BC_REASON_MSG_SELECTED,
1043                              (TIM_TIME_REF) 0, NULL,
1044                              cal_ref -> user_data );
1045 
1046 
1047   return;
1048 
1049 } /* messageCB */
1050 
1051 
1052 /*----------------------------------------------------------------------*/
1053 
1054 static void
monthSelectCB(Widget widget,MONTH_REF month_ref,XtPointer call_data)1055   monthSelectCB( Widget     widget,
1056                  MONTH_REF  month_ref,
1057                  XtPointer  call_data )
1058 {
1059 
1060   /* Variables. */
1061   TIM_TIME_REF  curr_date;
1062 
1063 
1064   /* Code. */
1065 
1066   /* Display this month. */
1067   curr_date = TimMakeTime( month_ref -> cal_ref -> curr_year,
1068                            month_ref -> month, 1, 0, 0, 0 );
1069 
1070   displayMonth( month_ref -> cal_ref, curr_date );
1071 
1072 
1073   return;
1074 
1075 } /* monthSelectCB */
1076 
1077 
1078 /*----------------------------------------------------------------------*/
1079 
1080 static void
scrollYearCB(Widget widget,SCROLL_YEAR_REF scroll_ref,XtPointer call_data)1081   scrollYearCB( Widget           widget,
1082                 SCROLL_YEAR_REF  scroll_ref,
1083                 XtPointer        call_data )
1084 {
1085 
1086   /* Variables. */
1087   int           to_year;
1088   TIM_TIME_REF  curr_date;
1089 
1090 
1091   /* Code. */
1092 
1093   /* In which direction yo we move? */
1094   if( scroll_ref -> direction == YEAR_PREV ) {
1095     to_year = scroll_ref -> cal_ref -> first_year_tab - NO_OF_YEAR_TABS + 1;
1096     if( to_year < 1971 )
1097       to_year = 1971;
1098   } else {
1099     to_year = scroll_ref -> cal_ref -> last_year_tab;
1100     if( to_year + NO_OF_YEAR_TABS > 2030 )
1101       to_year = 2030 - NO_OF_YEAR_TABS;
1102   }
1103 
1104 
1105   /* Set the new tabs. */
1106   setYearTabs( scroll_ref -> cal_ref, to_year );
1107 
1108 
1109   /* Display this month. */
1110   curr_date = TimMakeTime( to_year,
1111                            scroll_ref -> cal_ref -> curr_month,
1112                            1, 0, 0, 0 );
1113 
1114   displayMonth( scroll_ref -> cal_ref, curr_date );
1115 
1116 
1117   return;
1118 
1119 } /* scrollYearCB */
1120 
1121 
1122 /*----------------------------------------------------------------------*/
1123 
1124 static void
todayCB(Widget widget,CAL_REC_REF cal_ref,XtPointer call_data)1125   todayCB( Widget       widget,
1126            CAL_REC_REF  cal_ref,
1127            XtPointer    call_data )
1128 {
1129 
1130   /* Variables. */
1131   int           year;
1132   TIM_TIME_REF  curr_date;
1133   TIM_TIME_REF  now;
1134 
1135 
1136   /* Code. */
1137 
1138   /* Display today. */
1139   now       = TimLocalTime( TimMakeTimeNow() );
1140   curr_date = TimMakeTime( TimIndexOfYear( now ),
1141                            TimIndexOfMonth( now ), 1, 0, 0, 0 );
1142 
1143   year = TimIndexOfYear( now );
1144 
1145   if( cal_ref -> style == XTM_BC_STYLE_NOTEBOOK ) {
1146     if( year > 1971 )
1147       setYearTabs( cal_ref, year - 1 );
1148     else
1149       setYearTabs( cal_ref, year );
1150   }
1151 
1152   displayMonth( cal_ref, curr_date );
1153 
1154 
1155   return;
1156 
1157 } /* todayCB */
1158 
1159 
1160 /*----------------------------------------------------------------------*/
1161 
1162 static void
updateMonthCB(Widget widget,CAL_REC_REF cal_ref,XmUbMdiUpdateDayCallbackStruct * call_data)1163   updateMonthCB( Widget                          widget,
1164                  CAL_REC_REF                     cal_ref,
1165                  XmUbMdiUpdateDayCallbackStruct  *call_data )
1166 {
1167 
1168   /* Variables. */
1169   Boolean                 is_holiday;
1170   int                     index;
1171   Pixel                   color;
1172   XTM_GL_CUSTOM_DATA_REF  custom_data;
1173 
1174 
1175   /* Code. */
1176 
1177   custom_data = cal_ref -> appl_data_ref -> custom_data;
1178 
1179   /* Update week numbers. */
1180   if( call_data -> reason == XmUbCR_UPDATE_WEEK ) {
1181 
1182     call_data -> foreground = custom_data -> week_number_fg;
1183     call_data -> mapped = call_data -> default_mapped;
1184 
1185   } /* if */
1186 
1187 
1188   /* Update dates. */
1189   if( call_data -> reason == XmUbCR_UPDATE_DAY ) {
1190 
1191     /* Fetch entries defined? */
1192     if( call_data -> loop_index == 0 ) {
1193       cal_ref -> this_date = TimMakeTime( call_data -> year,
1194                                           call_data -> month,
1195                                           call_data -> day, 0, 0, 0 );
1196 
1197       for( index = 0; index < 6 * 7; index++ )
1198         cal_ref -> entry_defined[ index ] = False;
1199 
1200       if( cal_ref -> hasEntriesCB != NULL )
1201         (* cal_ref -> hasEntriesCB)( XTM_BC_REASON_ENTRIES_DEFINED,
1202                                      cal_ref -> user_data,
1203                                      cal_ref -> this_date, 6 * 7,
1204                                      cal_ref -> entry_defined );
1205     } else {
1206       TimAddDays( &cal_ref -> this_date, 1 );
1207 
1208     } /* if */
1209 
1210 
1211     /* Holidays. */
1212     is_holiday = xtmHoIsHoliday( cal_ref -> this_date );
1213 
1214 
1215     /* Find the foreground color. */
1216     color = custom_data -> week_number_fg;
1217 
1218     if( custom_data -> cal_button_style == 1 &&
1219         cal_ref -> entry_defined[ call_data -> loop_index ] )
1220       color = custom_data -> entry_exist_fg;
1221 
1222     else if( is_holiday )
1223       color = custom_data -> holiday_fg;
1224 
1225     else if( call_data -> which_month != XmUbCURRENT_MONTH )
1226       color = custom_data -> week_number_fg;
1227 
1228     else if( call_data -> weekday == 1 )
1229       color = custom_data -> monday_fg;
1230 
1231     else if( call_data -> weekday == 2 )
1232       color = custom_data -> tuesday_fg;
1233 
1234     else if( call_data -> weekday == 3 )
1235       color = custom_data -> wednesday_fg;
1236 
1237     else if( call_data -> weekday == 4 )
1238       color = custom_data -> thursday_fg;
1239 
1240     else if( call_data -> weekday == 5 )
1241       color = custom_data -> friday_fg;
1242 
1243     else if( call_data -> weekday == 6 )
1244       color = custom_data -> saturday_fg;
1245 
1246     else if( call_data -> weekday == 7 )
1247       color = custom_data -> sunday_fg;
1248 
1249     call_data -> foreground = color;
1250 
1251 
1252     /* Find the background color. */
1253     if( call_data -> today )
1254       color = custom_data -> today_bg;
1255     else
1256       color = custom_data -> date_mark_bg;
1257 
1258     call_data -> background = color;
1259 
1260 
1261     /* Find the shadow. */
1262     if( cal_ref -> entry_defined[ call_data -> loop_index ] ) {
1263       if( custom_data -> cal_button_style == 2 )
1264         color = custom_data -> entry_exist_fg;
1265       else
1266         color = custom_data -> date_mark_bg;
1267 
1268       if( custom_data -> cal_button_style == 3 )
1269         call_data -> use_shadows = True;
1270       else
1271         call_data -> use_shadows = False;
1272     } else {
1273       color = custom_data -> date_mark_bg;
1274       call_data -> use_shadows = False;
1275     }
1276 
1277     call_data -> frame = color;
1278 
1279 
1280     /* Extended month. */
1281     call_data -> mapped = call_data -> default_mapped;
1282 
1283    } /* if */
1284 
1285 
1286   return;
1287 
1288 } /* updateMonthCB */
1289 
1290 
1291 /*----------------------------------------------------------------------*/
1292 
1293 static void
yearSelectCB(Widget widget,YEAR_REF year_ref,XtPointer call_data)1294   yearSelectCB( Widget     widget,
1295                 YEAR_REF   year_ref,
1296                 XtPointer  call_data )
1297 {
1298 
1299   /* Variables. */
1300   TIM_TIME_REF  curr_date;
1301 
1302 
1303   /* Code. */
1304 
1305   /* Display this month. */
1306   curr_date = TimMakeTime( year_ref -> year,
1307                            year_ref -> cal_ref -> curr_month,
1308                            1, 0, 0, 0 );
1309 
1310   displayMonth( year_ref -> cal_ref, curr_date );
1311 
1312 
1313   return;
1314 
1315 } /* yearSelectCB */
1316