1 /*----------------------------------------------------------------------------
2 --
3 --  Module:           xtmReminder
4 --
5 --  Project:          Xdiary
6 --  System:           xtm - X Desktop Calendar
7 --    Subsystem:      <>
8 --    Function block: <>
9 --
10 --  Description:
11 --    A reminder tool with 'light-weight' alarms, i.e. alarms to remind
12 --    you of events during the day.
13 --
14 --  Filename:         xtmReminder.c
15 --
16 --  Authors:          Roger Larsson, Ulrika Bornetun
17 --  Creation date:    1992-02-16
18 --
19 --
20 --  (C) Copyright Ulrika Bornetun, Roger Larsson (1995)
21 --      All rights reserved
22 --
23 --  Permission to use, copy, modify, and distribute this software and its
24 --  documentation for any purpose and without fee is hereby granted,
25 --  provided that the above copyright notice appear in all copies. Ulrika
26 --  Bornetun and Roger Larsson make no representations about the usability
27 --  of this software for any purpose. It is provided "as is" without express
28 --  or implied warranty.
29 ----------------------------------------------------------------------------*/
30 
31 /* SCCS module identifier. */
32 static char SCCSID[] = "@(#) Module: xtmReminder.c, Version: 1.1, Date: 95/02/18 15:52:40";
33 
34 
35 /*----------------------------------------------------------------------------
36 --  Include files
37 ----------------------------------------------------------------------------*/
38 
39 #include <string.h>
40 #include <stdlib.h>
41 #include <stdio.h>
42 
43 #include <X11/Intrinsic.h>
44 #include <X11/Shell.h>
45 
46 #include <Xm/Protocols.h>
47 
48 #include <Xm/Xm.h>
49 #include <Xm/CascadeB.h>
50 #include <Xm/Frame.h>
51 #include <Xm/RowColumn.h>
52 #include <Xm/Scale.h>
53 #include <Xm/SeparatoG.h>
54 #include <Xm/Text.h>
55 #include <Xm/ToggleB.h>
56 
57 #include "System.h"
58 #include "Message.h"
59 #include "TimDate.h"
60 
61 #include "msgXdiary.h"
62 #include "xtmFormat.h"
63 #include "xtmHelp.h"
64 #include "xtmIcons.h"
65 #include "xitError.h"
66 #include "xitTools.h"
67 #include "XmUbTimeSl.h"
68 #include "xtmReminder.h"
69 
70 
71 /*----------------------------------------------------------------------------
72 --  Macro definitions
73 ----------------------------------------------------------------------------*/
74 
75 /* Local widgets in the reminder window. */
76 #define alarmActiveTb      dataLocalW[  0 ]
77 #define alarmTs            dataLocalW[  1 ]
78 #define alarmTx            dataLocalW[  2 ]
79 #define alarmTxLa          dataLocalW[  3 ]
80 #define hoSp               dataLocalW[  4 ]
81 #define menuBr             dataLocalW[  5 ]
82 #define remindFr           dataLocalW[  6 ]
83 #define remindLa           dataLocalW[  7 ]
84 #define remindRc           dataLocalW[  8 ]
85 #define remindSelLa        dataLocalW[  9 ]
86 #define todayLa            dataLocalW[ 10 ]
87 
88 
89 /* Local widgets in the alarm window. */
90 #define markerPx           dataLocalW[  0 ]
91 #define messageLa          dataLocalW[  1 ]
92 
93 
94 
95 /*----------------------------------------------------------------------------
96 --  Type declarations
97 ----------------------------------------------------------------------------*/
98 
99 
100 /*----------------------------------------------------------------------------
101 --  Global definitions
102 ----------------------------------------------------------------------------*/
103 
104 /* Name of module. */
105 static char  *module_name = "xtmReminder";
106 
107 /* Keyboard translations for newline in multi-line editor. */
108 static XtTranslations  newline_trans = NULL;
109 
110 static char newlineTrans[] =
111   "<Key>Return:    newline()";
112 
113 
114 /*----------------------------------------------------------------------------
115 --  Function prototypes
116 ----------------------------------------------------------------------------*/
117 
118 static void
119   alarmTimeChangedCB( Widget                        widget,
120                       XTM_RD_REMINDER_REF           reminder_ref,
121                       XmUbTimeSliderCallbackStruct  *call_ref );
122 
123 static void
124   alarmActiveCB( Widget                        widget,
125                  XTM_RD_REMINDER_REF           reminder_ref,
126                  XmToggleButtonCallbackStruct  *call_data );
127 
128 static void
129   alarmTimer( XTM_RD_REMINDER_REF  reminder_ref );
130 
131 static void
132   closeAlarmCB( Widget     widget,
133                 Widget     alarmW,
134                 XtPointer  call_data );
135 
136 static void
137   closeCB( Widget               widget,
138            XTM_RD_REMINDER_REF  reminder_ref,
139            XtPointer            call_data );
140 
141 static Widget
142   createReminderWindow( XTM_RD_REMINDER_REF  reminder_ref,
143                         Widget               parent );
144 
145 static void
146   giveAlarm( XTM_RD_REMINDER_REF  reminder_ref,
147              Widget               parent,
148              char                 *message );
149 
150 static void
151   helpCB( Widget                     widget,
152           XTM_RD_REMINDER_REF        reminder_ref,
153           XmRowColumnCallbackStruct  *call_data );
154 
155 static void
156   reminderSelectedCB( Widget                        widget,
157                       XTM_RD_REMINDER_REF           reminder_ref,
158                       XmToggleButtonCallbackStruct  *call_data );
159 
160 static void
161   resetCB( Widget               widget,
162            XTM_RD_REMINDER_REF  reminder_ref,
163            XtPointer            call_data );
164 
165 static void
166   setAlarmIndicators( XTM_RD_REMINDER_REF  reminder_ref,
167                       int                  reminder_no );
168 
169 static void
170   setWorkReminder( XTM_RD_REMINDER_REF  reminder_ref,
171                    int                  reminder_no );
172 
173 
174 /*----------------------------------------------------------------------------
175 --  Functions
176 ----------------------------------------------------------------------------*/
177 
178 XTM_RD_REMINDER_REF
xtmRdInitializeReminder(Widget parent,XtAppContext context,XTM_RD_CLOSE_CB closeCB,XTM_RD_HELP_CB helpCB,void * user_data)179   xtmRdInitializeReminder( Widget           parent,
180                            XtAppContext     context,
181                            XTM_RD_CLOSE_CB  closeCB,
182                            XTM_RD_HELP_CB   helpCB,
183                            void             *user_data )
184 {
185 
186   /* Variables. */
187   int                  index;
188   XTM_RD_REMINDER_REF  reminder_ref;
189 
190 
191   /* Code. */
192 
193   /* Initialize translations? */
194   if( newline_trans == NULL )
195     newline_trans = XtParseTranslationTable( newlineTrans );
196 
197 
198   reminder_ref = SysNew( XTM_RD_REMINDER );
199 
200   /* Default values. */
201   reminder_ref -> sliderCB_active   = True;
202   reminder_ref -> context           = context;
203   reminder_ref -> reminderW         = NULL;
204   reminder_ref -> curr_work_alarm   = 0;
205   reminder_ref -> closeCB           = closeCB;
206   reminder_ref -> helpCB            = helpCB;
207   reminder_ref -> user_data         = user_data;
208 
209   for( index = 0; index < XTM_RD_MAX_ALARMS; index++ ) {
210     reminder_ref -> alarm[ index ].active     = False;
211     reminder_ref -> alarm[ index ].alarm_time = 0;
212     reminder_ref -> alarm[ index ].text[ 0 ]  = '\0';
213   }
214 
215 
216   /* Create the reminder window. */
217   reminder_ref -> reminderW = createReminderWindow( reminder_ref,
218                                                     parent );
219 
220 
221   /* Start the alarm timer. */
222   alarmTimer( reminder_ref );
223 
224 
225   return( reminder_ref );
226 
227 } /* xtmRdInitializeReminder */
228 
229 
230 /*----------------------------------------------------------------------*/
231 
232 void
xtmRdDestroyReminder(XTM_RD_REMINDER_REF reminder_ref)233   xtmRdDestroyReminder( XTM_RD_REMINDER_REF  reminder_ref )
234 {
235 
236   /* Code. */
237 
238 
239   return;
240 
241 } /* xtmRdDestroyReminder */
242 
243 
244 /*----------------------------------------------------------------------*/
245 
246 void
xtmRdDisplayReminder(XTM_RD_REMINDER_REF reminder_ref)247   xtmRdDisplayReminder( XTM_RD_REMINDER_REF  reminder_ref )
248 {
249 
250   /* Variables. */
251   char    buffer[ 50 ];
252   Widget  tempW;
253 
254 
255   /* Code. */
256 
257   /* Is the reminder initialized? */
258   if( reminder_ref == NULL )
259     return;
260 
261 
262   /* Display the reminder being edited. */
263   sprintf( buffer, "RemindFr.RemindRc.Select%dTb",
264            reminder_ref -> curr_work_alarm + 1 );
265 
266   tempW = XtNameToWidget( reminder_ref -> reminderW,
267                           "RemindTlBase.RemindTlFo" );
268   tempW = XtNameToWidget( tempW, buffer );
269 
270   XmToggleButtonSetState( tempW, True, True );
271 
272 
273   /* Start at the text field. */
274   tempW = XtNameToWidget( reminder_ref -> reminderW,
275                           "RemindTlBase.RemindTlFo.AlarmTxSW.AlarmTx" );
276   xitGrabFocus( tempW );
277 
278 
279   /* Make the window visible (if not already). */
280   XtPopup( reminder_ref -> reminderW, XtGrabNone );
281 
282 
283   /* Make sure the window is visible. */
284   XRaiseWindow( XtDisplay( reminder_ref -> reminderW ),
285                 XtWindow(  reminder_ref -> reminderW ) );
286 
287   XtMapWidget( reminder_ref -> reminderW );
288 
289 
290   return;
291 
292 } /* xtmRdDisplayReminder */
293 
294 
295 /*----------------------------------------------------------------------*/
296 
297 void
xtmRdHideReminder(XTM_RD_REMINDER_REF reminder_ref)298   xtmRdHideReminder( XTM_RD_REMINDER_REF  reminder_ref )
299 {
300 
301   /* Code. */
302 
303   if( reminder_ref == NULL || reminder_ref -> reminderW == NULL )
304     return;
305 
306   XtPopdown( reminder_ref -> reminderW );
307 
308 
309   return;
310 
311 } /* xtmRdHideReminder */
312 
313 
314 /*----------------------------------------------------------------------*/
315 
316 Widget
xtmRdToplevelWindow(XTM_RD_REMINDER_REF reminder_ref)317   xtmRdToplevelWindow( XTM_RD_REMINDER_REF  reminder_ref )
318 {
319 
320   /* Code. */
321 
322   if( reminder_ref == NULL || reminder_ref -> reminderW == NULL )
323     return( NULL );
324 
325 
326   return( reminder_ref -> reminderW );
327 
328 } /* xtmRdToplevelWindow */
329 
330 
331 /*----------------------------------------------------------------------*/
332 
333 static void
alarmTimer(XTM_RD_REMINDER_REF reminder_ref)334   alarmTimer( XTM_RD_REMINDER_REF  reminder_ref )
335 {
336 
337   /* Variables. */
338   int           index;
339   int           next_minute;
340   char          buffer[ 50 ];
341   char          *char_ref;
342   Widget        mainFo;
343   Widget        tempW;
344   TIM_TIME_REF  alarm_time;
345   TIM_TIME_REF  now;
346 
347 
348   /* Code. */
349 
350   mainFo = XtNameToWidget( reminder_ref -> reminderW,
351                            "RemindTlBase.RemindTlFo" );
352 
353 
354   /* The time is.. */
355   now = TimLocalTime( TimMakeTimeNow() );
356 
357 
358   /* Update current date and time. */
359   xtmFoFormatFullTime( now, buffer, sizeof( buffer ) );
360 
361   tempW = XtNameToWidget( mainFo, "TodayLa" );
362   xitStringSetLabel( tempW, buffer );
363 
364 
365   /* If we have any alarms, show them. */
366   alarm_time = TimMakeTime( 1970, 1, 1,
367                             TimHour(   now ),
368                             TimMinute( now ), 0 );
369 
370   for( index = 0; index < XTM_RD_MAX_ALARMS; index++ ) {
371 
372     if( reminder_ref -> alarm[ index ].active &&
373         alarm_time == reminder_ref -> alarm[ index ].alarm_time ) {
374 
375       /* If reminder is current, take text from window. */
376       if( index == reminder_ref -> curr_work_alarm ) {
377         tempW = XtNameToWidget( mainFo, "AlarmTxSW.AlarmTx" );
378 
379         char_ref = xitStringGetText( tempW );
380 
381         strcpy( reminder_ref -> alarm[ index ].text, char_ref );
382 
383         SysFree( char_ref );
384       } /* if */
385 
386       giveAlarm( reminder_ref,
387                  reminder_ref -> reminderW,
388                  reminder_ref -> alarm[ index ].text );
389 
390       /* The alarm is not active anymore. */
391       reminder_ref -> alarm[ index ].active = False;
392 
393       setAlarmIndicators( reminder_ref, index );
394 
395       if( index == reminder_ref -> curr_work_alarm )
396         setWorkReminder( reminder_ref, index );
397 
398     } /* if */
399 
400   } /* loop */
401 
402 
403   /* Schedule the next wakeup call. */
404   next_minute = (60 - now % 60) * 1000;
405 
406   XtAppAddTimeOut( reminder_ref -> context,
407                    next_minute,
408                    (XtTimerCallbackProc) alarmTimer,
409                    (XtPointer) reminder_ref );
410 
411 
412   return;
413 
414 } /* alarmTimer */
415 
416 
417 /*----------------------------------------------------------------------*/
418 
419 static Widget
createReminderWindow(XTM_RD_REMINDER_REF reminder_ref,Widget parent)420   createReminderWindow( XTM_RD_REMINDER_REF  reminder_ref,
421                         Widget               parent )
422 {
423 
424   /* Variables. */
425   int       index;
426   char      buffer[ 100 ];
427   char      name[ 50 ];
428   Arg       args[ 10 ];
429   Cardinal  n;
430   Widget    dataLocalW[ 11 ];
431   Widget    menuCasc[ 2 ];
432   Widget    menuFileBu[ 1 ];
433   Widget    menuHelpBu[ 7 ];
434   Widget    pulldownMenu[ 2 ];
435   Widget    remindTl;
436   Widget    selectLa[ XTM_RD_MAX_ALARMS  ];
437   Widget    selectTb[ XTM_RD_MAX_ALARMS  ];
438   Widget    tempW;
439   Widget    workFo;
440 
441   static char  *pull_downs[] = { "pdown1", "pdown2" };
442 
443   static XIT_TEXT_STRUCT text_field_def[] = {
444     { "AlarmTx", NULL, 5, True },
445   };
446 
447   static XIT_CASCADE_STRUCT menupane[] = {
448     { "", "", "FilePane" },
449     { "", "", "HelpPane" }
450   };
451 
452   static XIT_MENU_BUTTON_STRUCT file_casc[] = {
453     { "", "", NULL, "CloseBu", True, False, False },
454   };
455 
456   static XIT_MENU_BUTTON_STRUCT help_casc[] = {
457     { "", "", NULL, "ContextBu", True, False, False },
458     { "", "", NULL, "WindowsBu", True, False, False },
459     { "", "", NULL, "KeysBu",    True, False, False },
460     { "", "", NULL, "IndexBu",   True, False, False },
461     { "", "", NULL, "HelpBu",    True, False, False },
462     { "", "", NULL, "VersionBu", True, False, False },
463     { "", "", NULL, "AboutBu",   True, False, False },
464   };
465 
466   static XIT_ACTION_AREA_ITEM  action_buttons[] = {
467     { "",   closeCB, NULL },
468     { NULL, NULL,    NULL },
469     { NULL, NULL,    NULL },
470     { NULL, NULL,    NULL },
471     { "",   resetCB, NULL },
472   };
473 
474 
475   /* Code. */
476 
477   /* Get text for menues and buttons. */
478   action_buttons[ 0 ].label = msgGetText( MXDI_CLOSE_BUTTON );
479   action_buttons[ 0 ].data  = reminder_ref;
480   action_buttons[ 4 ].label = msgGetText( MXDI_RESET_BUTTON );
481   action_buttons[ 4 ].data  = reminder_ref;
482 
483   menupane[ 0 ].title    = msgGetText( MXDI_FILE_MENU );
484   menupane[ 0 ].mnemonic = msgGetText( MXDI_FILE_MENU_ACC );
485   menupane[ 1 ].title    = msgGetText( MXDI_HELP_MENU );
486   menupane[ 1 ].mnemonic = msgGetText( MXDI_HELP_MENU_ACC );
487 
488   file_casc[ 0 ].title    = msgGetText( MXDI_CLOSE_MENU );
489   file_casc[ 0 ].mnemonic = msgGetText( MXDI_CLOSE_MENU_ACC );
490 
491   help_casc[ 0 ].title    = msgGetText( MXDI_HELP_CONTEXT );
492   help_casc[ 0 ].mnemonic = msgGetText( MXDI_HELP_CONTEXT_ACC );
493   help_casc[ 1 ].title    = msgGetText( MXDI_HELP_WINDOWS );
494   help_casc[ 1 ].mnemonic = msgGetText( MXDI_HELP_WINDOWS_ACC );
495   help_casc[ 2 ].title    = msgGetText( MXDI_HELP_KEYS );
496   help_casc[ 2 ].mnemonic = msgGetText( MXDI_HELP_KEYS_ACC );
497   help_casc[ 3 ].title    = msgGetText( MXDI_HELP_INDEX );
498   help_casc[ 3 ].mnemonic = msgGetText( MXDI_HELP_INDEX_ACC );
499   help_casc[ 4 ].title    = msgGetText( MXDI_HELP_HELP );
500   help_casc[ 4 ].mnemonic = msgGetText( MXDI_HELP_HELP_ACC );
501   help_casc[ 5 ].title    = msgGetText( MXDI_HELP_VERSION );
502   help_casc[ 5 ].mnemonic = msgGetText( MXDI_HELP_VERSION_ACC );
503   help_casc[ 6 ].title    = msgGetText( MXDI_HELP_ABOUT );
504   help_casc[ 6 ].mnemonic = msgGetText( MXDI_HELP_ABOUT_ACC );
505 
506 
507   /* Create a separate window. */
508   tempW = xitGetToplevelWidget( parent );
509 
510   remindTl = xitCreateToplevelDialog( tempW, "RemindTl",
511                                       1, 0,
512                                       action_buttons,
513                                       XtNumber( action_buttons ) );
514 
515   sprintf( buffer, "%s", msgGetText( MXDI_REMINDER_TITLE ) );
516 
517   n = 0;
518   XtSetArg( args[ n ], XmNtitle, buffer ); n++;
519   XtSetValues( remindTl, args, n );
520 
521   sprintf( buffer, "%s", msgGetText( MXDI_REMINDER_IC_TITLE ) );
522 
523   n = 0;
524   XtSetArg( args[ n ], XmNiconName, buffer ); n++;
525   XtSetValues( remindTl, args, n );
526 
527   /* Close the window if this window is deleted. */
528   {
529     Atom  wm_delete_window;
530 
531     wm_delete_window = XmInternAtom( XtDisplay( remindTl ),
532                                      "WM_DELETE_WINDOW", False );
533 
534     XmAddWMProtocols( remindTl, &wm_delete_window, 1 );
535     XmAddWMProtocolCallback( remindTl, wm_delete_window,
536                              (XtCallbackProc) closeCB,
537                              (XtPointer) reminder_ref );
538   } /* block */
539 
540 
541   /* Form to enclose the show window. */
542   workFo = XtNameToWidget( remindTl, "RemindTlBase.RemindTlFo" );
543 
544 
545   /* Create the menubar and menu cascades. */
546   menuBr = XmCreateMenuBar( workFo, "MenuBr", args, 0 );
547 
548   n = 0;
549   for( index = 0; index < XtNumber( pulldownMenu ); index++ )
550     pulldownMenu[ index ] = XmCreatePulldownMenu( menuBr,
551                                                   pull_downs[ index ],
552                                                   NULL, n );
553 
554   for( index = 0; index < XtNumber( menuCasc ); index++ )
555     menuCasc[ index ] = xitCreateCascadeButton( menuBr,
556                                                 pulldownMenu[ index ],
557                                                 &menupane[ index ] );
558 
559   /* The help button should be placed to the right. */
560   index = XtNumber( menuCasc ) - 1;
561   n     = 0;
562   XtSetArg( args[ n ], XmNmenuHelpWidget, menuCasc[ index ] ); n++;
563   XtSetValues( menuBr, args, n );
564 
565 
566   /* Create the file menu. */
567   for( index = 0; index < XtNumber( menuFileBu ); index++ )
568     menuFileBu[ index ] = xitCreateMenuPushButton( pulldownMenu[ 0 ],
569                                                    &file_casc[ index ] );
570 
571   XtAddCallback( menuFileBu[ 0 ], XmNactivateCallback,
572                  (XtCallbackProc) closeCB, (XtPointer) reminder_ref );
573 
574   /* Create the help menu. */
575   XtAddCallback( pulldownMenu[ 1 ], XmNentryCallback,
576                  (XtCallbackProc) helpCB, (XtPointer) reminder_ref );
577 
578   for( index = 0; index < XtNumber( menuHelpBu ); index++ ) {
579     menuHelpBu[ index ] = xitCreateMenuPushButton( pulldownMenu[ 1 ],
580                                                    &help_casc[ index ] );
581 
582     XtAddCallback( menuHelpBu[ index ], XmNactivateCallback,
583                    (XtCallbackProc) helpCB, (XtPointer)(intptr_t)index );
584   }
585 
586   /* We can't do context sensitive help. */
587   XtSetSensitive( menuHelpBu[ 0 ], False );
588 
589 
590   /* Current date and time label. */
591   todayLa = xitCreateLabel( workFo, "TodayLa", " \n ", XmALIGNMENT_CENTER );
592 
593 
594   /* Reminder label. */
595   remindLa = xitCreateLabel( workFo, "RemindLa",
596                              msgGetText( MXDI_REMINDERS_LABEL ), -1 );
597 
598 
599   /* The different reminders we have. */
600   n = 0;
601   remindFr = XmCreateFrame( workFo, "RemindFr", args, n );
602 
603   n = 0;
604   XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL ); n++;
605   XtSetArg( args[ n ], XmNpacking, XmPACK_COLUMN ); n++;
606   XtSetArg( args[ n ], XmNnumColumns, 2 ); n++;
607   XtSetArg( args[ n ], XmNradioBehavior, True ); n++;
608   XtSetArg( args[ n ], XmNisHomogeneous, False ); n++;
609   remindRc = XmCreateRowColumn( remindFr, "RemindRc", args, n );
610 
611 
612   /* Reminders selectors and alarm times. */
613   for( index = 0; index < XTM_RD_MAX_ALARMS; index++ ) {
614     sprintf( name,   "Select%dTb", index + 1 );
615     sprintf( buffer, "%d",         index + 1 );
616 
617     selectTb[ index ] = xitCreateToggleButton( remindRc, name,
618                                                buffer, False );
619 
620     XtAddCallback( selectTb[ index ],  XmNvalueChangedCallback,
621                    (XtCallbackProc) reminderSelectedCB,
622                    (XtPointer) reminder_ref );
623   }
624 
625   n = 0;
626   XtSetArg( args[ n ], XmNisHomogeneous, False ); n++;
627   XtSetValues( remindRc, args, n );
628 
629   for( index = 0; index < XTM_RD_MAX_ALARMS; index++ ) {
630     sprintf( name,   "Select%dLa", index + 1 );
631     sprintf( buffer, "%-8.8s", " " );
632 
633     selectLa[ index ] = xitCreateLabel( remindRc, name, buffer, -1 );
634   }
635 
636 
637   /* Separator. */
638   n = 0;
639   XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL );  n++;
640   hoSp = XmCreateSeparatorGadget( workFo, "HoSp", args, n );
641 
642 
643   /* The 'reminder definition' part. */
644 
645   /* Which reminder are we using? */
646   remindSelLa = xitCreateLabel( workFo, "RemindSelLa", " ",
647                                 XmALIGNMENT_BEGINNING );
648 
649 
650   /* Scale to select alarm time. */
651   n = 0;
652   alarmTs = XmUbCreateTimeSlider( workFo, "AlarmTs", args, n );
653   XtAddCallback( alarmTs, XmNvalueChangedCallback,
654                  (XtCallbackProc) alarmTimeChangedCB,
655                  (XtPointer) reminder_ref );
656 
657 
658 
659   /* Button to select if reminder is active or not. */
660   alarmActiveTb = xitCreateToggleButton(
661                     workFo, "AlarmActiveTb",
662                     msgGetText( MXDI_REMINDERS_ACTIVE_LABEL ), False );
663 
664   XtAddCallback( alarmActiveTb, XmNvalueChangedCallback,
665                  (XtCallbackProc) alarmActiveCB, (XtPointer) reminder_ref );
666 
667 
668   /* Alarm text label. */
669   alarmTxLa = xitCreateLabel( workFo, "AlarmTxLa",
670                               msgGetText( MXDI_TEXT_LABEL ), -1 );
671 
672   /* Alarm text to display. */
673   alarmTx = xitCreateTextScrolled( workFo, &text_field_def[ 0 ] );
674 
675   XtOverrideTranslations( alarmTx, newline_trans );
676 
677   n = 0;
678   XtSetArg( args[ n ], XmNmaxLength, XTM_RD_MAX_ALARM_TEXT ); n++;
679   XtSetValues( alarmTx, args, n );
680 
681 
682   /* Put the parts together. */
683   xitAttachWidget( menuBr,
684                    XmATTACH_FORM, NULL, XmATTACH_FORM, NULL,
685                    XmATTACH_FORM, NULL, XmATTACH_NONE, NULL );
686   xitAttachWidget( todayLa,
687                    XmATTACH_WIDGET, menuBr, XmATTACH_FORM, NULL,
688                    XmATTACH_FORM,   NULL,   XmATTACH_NONE, NULL );
689   xitAttachWidget( remindLa,
690                    XmATTACH_WIDGET, todayLa, XmATTACH_FORM, NULL,
691                    XmATTACH_NONE,   NULL,    XmATTACH_NONE, NULL );
692   xitAttachWidget( remindFr,
693                    XmATTACH_WIDGET, remindLa, XmATTACH_FORM, NULL,
694                    XmATTACH_NONE,   NULL,     XmATTACH_NONE, NULL );
695   xitAttachWidget( hoSp,
696                    XmATTACH_WIDGET, remindFr, XmATTACH_FORM, NULL,
697                    XmATTACH_FORM,   NULL,     XmATTACH_NONE, NULL );
698   xitAttachWidget( remindSelLa,
699                    XmATTACH_WIDGET, hoSp, XmATTACH_FORM, NULL,
700                    XmATTACH_FORM,   NULL, XmATTACH_NONE, NULL );
701   xitAttachWidget( alarmTs,
702                    XmATTACH_WIDGET, remindSelLa, XmATTACH_FORM, NULL,
703                    XmATTACH_FORM,   NULL,        XmATTACH_NONE, NULL );
704   xitAttachWidget( alarmActiveTb,
705                    XmATTACH_WIDGET, alarmTs, XmATTACH_FORM, NULL,
706                    XmATTACH_NONE,   NULL,    XmATTACH_NONE, NULL );
707   xitAttachWidget( alarmTxLa,
708                    XmATTACH_WIDGET, alarmActiveTb, XmATTACH_FORM, NULL,
709                    XmATTACH_NONE,   NULL,          XmATTACH_NONE, NULL );
710   xitAttachWidget( XtParent( alarmTx ),
711                    XmATTACH_WIDGET, alarmTxLa, XmATTACH_FORM, NULL,
712                    XmATTACH_NONE,   NULL,      XmATTACH_NONE, NULL );
713 
714 
715   /* Make sure there is enough space between the children. */
716   n = 0;
717   XtSetArg( args[ n ], XmNtopOffset,    5 ); n++;
718   XtSetArg( args[ n ], XmNleftOffset,   5 ); n++;
719   XtSetArg( args[ n ], XmNrightOffset,  5 ); n++;
720   XtSetArg( args[ n ], XmNbottomOffset, 5 ); n++;
721   XtSetValues( todayLa,             args, n );
722   XtSetValues( remindLa,            args, n );
723   XtSetValues( remindFr,            args, n );
724   XtSetValues( remindSelLa,         args, n );
725   XtSetValues( alarmTs,             args, n );
726   XtSetValues( alarmActiveTb,       args, n );
727   XtSetValues( alarmTxLa,           args, n );
728   XtSetValues( XtParent( alarmTx ), args, n );
729 
730   n = 0;
731   XtSetArg( args[ n ], XmNtopOffset, 5 ); n++;
732   XtSetValues( hoSp, args, n );
733 
734   /* Manage all the children. */
735   XtManageChildren( menuCasc,     XtNumber( menuCasc ) );
736   XtManageChildren( menuFileBu,   XtNumber( menuFileBu ) );
737   XtManageChildren( menuHelpBu,   XtNumber( menuHelpBu ) );
738   XtManageChildren( pulldownMenu, XtNumber( pulldownMenu ) );
739   XtManageChildren( selectTb,     XtNumber( selectTb ) );
740   XtManageChildren( selectLa,     XtNumber( selectLa ) );
741 
742   xitManageChildren( dataLocalW,  XtNumber( dataLocalW ) );
743 
744 
745   /* Set icon for this window. */
746   xtmIcSetSimpleIcon( remindTl, workFo, XTM_IC_ICON_REMINDER );
747 
748   /* Set the size of the window. */
749   xitSetSizeToplevelDialog( remindTl, True );
750 
751 
752   /* Make the final attachments. */
753   n = 0;
754   XtSetArg( args[ n ], XmNrightAttachment,  XmATTACH_FORM ); n++;
755   XtSetArg( args[ n ], XmNbottomAttachment, XmATTACH_FORM ); n++;
756   XtSetValues( XtParent( alarmTx ), args, n );
757 
758 
759   return( remindTl );
760 
761 } /* createReminderWindow */
762 
763 
764 /*----------------------------------------------------------------------*/
765 
766 static void
giveAlarm(XTM_RD_REMINDER_REF reminder_ref,Widget parent,char * message)767   giveAlarm( XTM_RD_REMINDER_REF  reminder_ref,
768              Widget               parent,
769              char                 *message )
770 {
771 
772   /* Variables. */
773   char      buffer[ 100 ];
774   Arg       args[ 10 ];
775   Cardinal  n;
776   Widget    dataLocalW[ 2 ];
777   Widget    remindAlarmTl;
778   Widget    workFo;
779   Widget    tempW;
780 
781   static Pixmap  normal_pixmap = None;
782 
783   static XIT_ACTION_AREA_ITEM  action_buttons[] = {
784     { NULL, NULL, NULL },
785     { "",   NULL, NULL },
786     { NULL, NULL, NULL },
787   };
788 
789 
790   /* Code. */
791 
792   action_buttons[ 1 ].label = msgGetText( MXDI_ALARM_CONFIRM );
793 
794   if( message == NULL || *message == '\0' )
795     message = "---";
796 
797   /* Create a separate window. */
798   tempW = xitGetToplevelWidget( parent );
799 
800   remindAlarmTl = xitCreateToplevelDialog( tempW, "RemindAlarmTl",
801                                            2, 0,
802                                            action_buttons,
803                                            XtNumber( action_buttons ) );
804 
805   sprintf( buffer, "%s", msgGetText( MXDI_REMINDER_ALARM_TITLE ) );
806 
807   n = 0;
808   XtSetArg( args[ n ], XmNtitle,    buffer ); n++;
809   XtSetArg( args[ n ], XmNiconName, buffer ); n++;
810   XtSetValues( remindAlarmTl, args, n );
811 
812 
813   /* Catch when the user seslects Close from the system menu. */
814   {
815     Atom  wm_delete_window;
816 
817     wm_delete_window = XmInternAtom( XtDisplay( remindAlarmTl ),
818                                      "WM_DELETE_WINDOW", False );
819 
820     XmAddWMProtocols( remindAlarmTl, &wm_delete_window, 1 );
821     XmAddWMProtocolCallback( remindAlarmTl, wm_delete_window,
822                              (XtCallbackProc) closeAlarmCB,
823                              (XtPointer) remindAlarmTl );
824   } /* block */
825 
826 
827 
828   /* Form to hold the alarm message. */
829   workFo = XtNameToWidget( remindAlarmTl,
830                            "RemindAlarmTlBase.RemindAlarmTlFo" );
831 
832 
833   /* Pixelmap label. */
834   markerPx = xitCreateLabel( workFo, "MarkerPx", "", -1 );
835 
836 
837   /* Fetch the alarm pixmap. */
838   if( normal_pixmap == None )
839     normal_pixmap = xtmIcFetchSimplePixmap( workFo,
840                                             XTM_IC_ICON_ALARM_CLOCK5, False );
841 
842   n = 0;
843   XtSetArg( args[ n ], XmNlabelPixmap, normal_pixmap ); n++;
844   XtSetArg( args[ n ], XmNlabelType,   XmPIXMAP      ); n++;
845   XtSetValues( markerPx, args, n );
846 
847 
848   /* Message label. */
849   messageLa = xitCreateLabel( workFo, "MessageLa",
850                               message, XmALIGNMENT_BEGINNING );
851 
852 
853   /* Put the Parts together. */
854   xitAttachWidget( markerPx,
855                    XmATTACH_FORM, NULL, XmATTACH_FORM, NULL,
856                    XmATTACH_NONE, NULL, XmATTACH_NONE, NULL );
857   xitAttachWidget( messageLa,
858                    XmATTACH_FORM, NULL, XmATTACH_WIDGET, markerPx,
859                    XmATTACH_NONE, NULL, XmATTACH_NONE,   NULL );
860 
861 
862   /* Make sure there is enough space between the children. */
863   n = 0;
864   XtSetArg( args[ n ], XmNtopOffset,    5 ); n++;
865   XtSetArg( args[ n ], XmNleftOffset,   5 ); n++;
866   XtSetArg( args[ n ], XmNrightOffset,  5 ); n++;
867   XtSetArg( args[ n ], XmNbottomOffset, 5 ); n++;
868   XtSetValues( markerPx,  args, n );
869   XtSetValues( messageLa, args, n );
870 
871 
872   /* Manage the widgets. */
873   xitManageChildren( dataLocalW, XtNumber( dataLocalW ) );
874 
875 
876   /* Set icon for this window. */
877   xtmIcSetSimpleIcon( remindAlarmTl, workFo, XTM_IC_ICON_DEFAULT );
878 
879   /* Set the size of the window. */
880   xitSetSizeToplevelDialog( remindAlarmTl, True );
881 
882 
883   XtPopup( remindAlarmTl, XtGrabNone );
884 
885 
886   /* Give an alarm, just a boring bell. */
887   XBell( XtDisplay( remindAlarmTl ), 100 );
888 
889 
890   return;
891 
892 } /* giveAlarm */
893 
894 
895 /*----------------------------------------------------------------------*/
896 
897 static void
setAlarmIndicators(XTM_RD_REMINDER_REF reminder_ref,int reminder_no)898   setAlarmIndicators( XTM_RD_REMINDER_REF  reminder_ref,
899                       int                  reminder_no )
900 {
901 
902   /* Variables. */
903   int     index;
904   char    buffer[ 50 ];
905   Widget  mainFo;
906   Widget  tempW;
907 
908 
909   /* Code. */
910 
911   mainFo = XtNameToWidget( reminder_ref -> reminderW,
912                            "RemindTlBase.RemindTlFo" );
913 
914   /* Display alarm times. */
915   for( index = 0; index < XTM_RD_MAX_ALARMS; index++ ) {
916 
917     sprintf( buffer, "RemindFr.RemindRc.Select%dLa", index + 1 );
918     tempW = XtNameToWidget( mainFo, buffer );
919 
920     if( reminder_ref -> alarm[ index ].active )
921       xtmFoFormatTime( reminder_ref -> alarm[ index ].alarm_time,
922                        buffer, sizeof( buffer ) );
923     else
924       sprintf( buffer, "%-8.8s", " " );
925 
926     if( reminder_no < 0 || reminder_no == index )
927       xitStringSetLabel( tempW, buffer );
928 
929   } /* loop */
930 
931 
932   return;
933 
934 } /* setAlarmIndicators */
935 
936 
937 /*----------------------------------------------------------------------*/
938 
939 static void
setWorkReminder(XTM_RD_REMINDER_REF reminder_ref,int reminder_no)940   setWorkReminder( XTM_RD_REMINDER_REF  reminder_ref,
941                    int                  reminder_no )
942 {
943 
944   /* Variables. */
945   Boolean       sliderCB_active;
946   char          buffer[ 50 ];
947   Widget        mainFo;
948   Widget        tempW;
949   TIM_TIME_REF  alarm_time;
950 
951 
952   /* Code. */
953 
954   mainFo = XtNameToWidget( reminder_ref -> reminderW,
955                            "RemindTlBase.RemindTlFo" );
956 
957 
958   /* Set the label telling wich reminder we are editing. */
959   sprintf( buffer, msgGetText( MXDI_REMINDER_WORK_LABEL ),
960            reminder_no + 1 );
961 
962   tempW = XtNameToWidget( mainFo, "RemindSelLa" );
963   xitStringSetLabel( tempW, buffer );
964 
965 
966   /* Set the alarm time. */
967   if( ! reminder_ref -> alarm[ reminder_no ].active &&
968         reminder_ref -> alarm[ reminder_no ].alarm_time == 0 )
969     reminder_ref -> alarm[ reminder_no ].alarm_time =
970       TimLocalTime( TimMakeTimeNow() );
971 
972   alarm_time = reminder_ref -> alarm[ reminder_no ].alarm_time;
973 
974 
975   /* Time scale. */
976   tempW = XtNameToWidget( mainFo, "AlarmTs" );
977 
978   sliderCB_active = reminder_ref -> sliderCB_active;
979   reminder_ref -> sliderCB_active = False;
980 
981   XmUbTimeSliderSetTime( tempW, alarm_time );
982 
983   reminder_ref -> sliderCB_active = sliderCB_active;
984 
985 
986   /* Reminder is active? */
987   tempW = XtNameToWidget( mainFo, "AlarmActiveTb" );
988   XmToggleButtonSetState( tempW,
989                           reminder_ref -> alarm[ reminder_no ].active,
990                           False );
991 
992 
993   /* Alarm text. */
994   tempW = XtNameToWidget( mainFo, "AlarmTxSW.AlarmTx" );
995 
996   if( reminder_ref -> alarm[ reminder_no ].active ||
997       reminder_ref -> alarm[ reminder_no ].text[ 0 ] != '\0' )
998     XmTextSetString( tempW, reminder_ref -> alarm[ reminder_no ].text );
999 
1000 
1001   /* Set the alarm indicators. */
1002   setAlarmIndicators( reminder_ref, reminder_no );
1003 
1004 
1005   return;
1006 
1007 } /* setWorkReminder */
1008 
1009 
1010 /*----------------------------------------------------------------------*/
1011 
1012 static void
alarmActiveCB(Widget widget,XTM_RD_REMINDER_REF reminder_ref,XmToggleButtonCallbackStruct * call_data)1013   alarmActiveCB( Widget                        widget,
1014                  XTM_RD_REMINDER_REF           reminder_ref,
1015                  XmToggleButtonCallbackStruct  *call_data )
1016 {
1017 
1018   /* Variables. */
1019 
1020 
1021   /* Code. */
1022 
1023   /* Alarm indicators. */
1024   if( call_data -> set )
1025     reminder_ref -> alarm[ reminder_ref -> curr_work_alarm ].active = True;
1026   else
1027     reminder_ref -> alarm[ reminder_ref -> curr_work_alarm ].active = False;
1028 
1029 
1030   /* Set the alarm indicators. */
1031   setAlarmIndicators( reminder_ref, reminder_ref -> curr_work_alarm );
1032 
1033 
1034   return;
1035 
1036 } /* alarmActiveCB */
1037 
1038 
1039 /*----------------------------------------------------------------------*/
1040 
1041 static void
closeCB(Widget widget,XTM_RD_REMINDER_REF reminder_ref,XtPointer call_data)1042   closeCB( Widget               widget,
1043            XTM_RD_REMINDER_REF  reminder_ref,
1044            XtPointer            call_data )
1045 {
1046 
1047   /* Code. */
1048 
1049   if( reminder_ref -> closeCB == NULL ) {
1050     XtPopdown( reminder_ref -> reminderW );
1051 
1052     return;
1053   }
1054 
1055 
1056   /* Call the user callback. */
1057   (* reminder_ref -> closeCB)( reminder_ref -> reminderW,
1058                                reminder_ref -> user_data,
1059                                reminder_ref );
1060 
1061 
1062   return;
1063 
1064 } /* closeCB */
1065 
1066 
1067 /*----------------------------------------------------------------------*/
1068 
1069 static void
closeAlarmCB(Widget widget,Widget alarmW,XtPointer call_data)1070   closeAlarmCB( Widget     widget,
1071                 Widget     alarmW,
1072                 XtPointer  call_data )
1073 {
1074 
1075   /* Code. */
1076 
1077   XtDestroyWidget( alarmW );
1078 
1079 
1080   return;
1081 
1082 } /* closeAlarmCB */
1083 
1084 
1085 /*----------------------------------------------------------------------*/
1086 
1087 static void
helpCB(Widget widget,XTM_RD_REMINDER_REF reminder_ref,XmRowColumnCallbackStruct * call_data)1088   helpCB( Widget                     widget,
1089           XTM_RD_REMINDER_REF        reminder_ref,
1090           XmRowColumnCallbackStruct  *call_data )
1091 {
1092 
1093   /* Code. */
1094 
1095   /* About window? */
1096   if( (intptr_t) call_data -> data == 6 ) {
1097     xtmHlDisplayAboutWindow( reminder_ref -> reminderW );
1098 
1099     return;
1100   }
1101 
1102   if( reminder_ref -> helpCB == NULL )
1103     return;
1104 
1105   /* Call the user callback. */
1106   (* reminder_ref -> helpCB)( reminder_ref -> reminderW,
1107                               reminder_ref -> user_data,
1108                               (intptr_t) call_data -> data );
1109 
1110 
1111   return;
1112 
1113 } /* helpCB */
1114 
1115 
1116 /*----------------------------------------------------------------------*/
1117 
1118 static void
reminderSelectedCB(Widget widget,XTM_RD_REMINDER_REF reminder_ref,XmToggleButtonCallbackStruct * call_data)1119   reminderSelectedCB( Widget                        widget,
1120                       XTM_RD_REMINDER_REF           reminder_ref,
1121                       XmToggleButtonCallbackStruct  *call_data )
1122 {
1123 
1124   /* Variables. */
1125   int     index;
1126   char    buffer[ 50 ];
1127   char    *char_ref;
1128   Widget  mainFo;
1129   Widget  tempW;
1130 
1131 
1132   /* Code. */
1133 
1134   mainFo = XtNameToWidget( reminder_ref -> reminderW,
1135                            "RemindTlBase.RemindTlFo" );
1136 
1137   if( ! call_data -> set ) {
1138     tempW = XtNameToWidget( mainFo, "AlarmTxSW.AlarmTx" );
1139 
1140     char_ref = xitStringGetText( tempW );
1141     strcpy( reminder_ref -> alarm[ reminder_ref -> curr_work_alarm ].text,
1142             char_ref );
1143 
1144     SysFree( char_ref );
1145 
1146     return;
1147   }
1148 
1149 
1150   /* Find the index of the reminder selected. */
1151   for( index = 0; index < XTM_RD_MAX_ALARMS; index++ ) {
1152     sprintf( buffer, "RemindFr.RemindRc.Select%dTb", index + 1 );
1153 
1154     tempW = XtNameToWidget( mainFo, buffer );
1155     if( tempW == widget )
1156       break;
1157   }
1158 
1159   reminder_ref -> curr_work_alarm = index;
1160 
1161 
1162   /* Display the selected reminder. */
1163   setWorkReminder( reminder_ref, reminder_ref -> curr_work_alarm );
1164 
1165 
1166   return;
1167 
1168 } /* reminderSelectedCB */
1169 
1170 
1171 /*----------------------------------------------------------------------*/
1172 
1173 static void
resetCB(Widget widget,XTM_RD_REMINDER_REF reminder_ref,XtPointer call_data)1174   resetCB( Widget               widget,
1175            XTM_RD_REMINDER_REF  reminder_ref,
1176            XtPointer            call_data )
1177 {
1178 
1179   /* Variables. */
1180   int     index;
1181   Widget  mainFo;
1182   Widget  tempW;
1183 
1184 
1185   /* Code. */
1186 
1187   mainFo = XtNameToWidget( reminder_ref -> reminderW,
1188                            "RemindTlBase.RemindTlFo" );
1189 
1190   index = reminder_ref -> curr_work_alarm;
1191 
1192   /* The alarm is not active. */
1193   reminder_ref -> alarm[ index ].active     = False;
1194   reminder_ref -> alarm[ index ].alarm_time = 0;
1195   reminder_ref -> alarm[ index ].text[ 0 ]  = '\0';
1196 
1197   setWorkReminder( reminder_ref, index );
1198 
1199   tempW = XtNameToWidget( mainFo, "AlarmTxSW.AlarmTx" );
1200   XmTextSetString( tempW, reminder_ref -> alarm[ index ].text );
1201 
1202 
1203   return;
1204 
1205 } /* resetCB */
1206 
1207 
1208 /*----------------------------------------------------------------------*/
1209 
1210 static void
alarmTimeChangedCB(Widget widget,XTM_RD_REMINDER_REF reminder_ref,XmUbTimeSliderCallbackStruct * call_ref)1211   alarmTimeChangedCB( Widget                        widget,
1212                       XTM_RD_REMINDER_REF           reminder_ref,
1213                       XmUbTimeSliderCallbackStruct  *call_ref )
1214 {
1215 
1216   /* Variables. */
1217   Widget             mainFo;
1218   Widget             tempW;
1219   TIM_TIME_REF       alarm_time;
1220   XTM_RD_ALARM_INFO  *this_alarm;
1221 
1222 
1223   /* Code. */
1224 
1225   if( ! reminder_ref -> sliderCB_active )
1226     return;
1227 
1228   this_alarm = &reminder_ref -> alarm[ reminder_ref -> curr_work_alarm ];
1229 
1230   mainFo = XtNameToWidget( reminder_ref -> reminderW,
1231                            "RemindTlBase.RemindTlFo" );
1232 
1233   /* Fetch the alarm time. */
1234   alarm_time = XmUbTimeSliderGetTime( widget );
1235 
1236   /* Do we already have this alarm time? */
1237   if( this_alarm -> alarm_time == alarm_time )
1238     return;
1239 
1240   /* Save the alarm time. */
1241   this_alarm -> alarm_time = alarm_time;
1242 
1243 
1244   /* If an alarm was not active, make it active. */
1245   if( ! this_alarm -> active ) {
1246     tempW = XtNameToWidget( mainFo, "AlarmActiveTb" );
1247 
1248     XmToggleButtonSetState( tempW, True, True );
1249   }
1250 
1251 
1252   /* Update the alarm indicator). */
1253   setAlarmIndicators( reminder_ref, reminder_ref -> curr_work_alarm );
1254 
1255 
1256   return;
1257 
1258 } /* alarmTimeChangedCB */
1259