1 /*----------------------------------------------------------------------------
2 --
3 --  Module:           xtmMsgSend
4 --
5 --  Project:          Xdiary
6 --  System:           xtm - X Desktop Calendar
7 --    Subsystem:      <>
8 --    Function block: <>
9 --
10 --  Description:
11 --    Send an XDiary message to one or more users.
12 --
13 --  Filename:         xtmMsgSend.c
14 --
15 --  Authors:          Roger Larsson, Ulrika Bornetun
16 --  Creation date:    1992-04-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: xtmMsgSend.c, Version: 1.1, Date: 95/02/18 15:52:34";
32 
33 
34 /*----------------------------------------------------------------------------
35 --  Include files
36 ----------------------------------------------------------------------------*/
37 
38 #include <string.h>
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <ctype.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/Frame.h>
50 #include <Xm/List.h>
51 #include <Xm/RowColumn.h>
52 #include <Xm/SeparatoG.h>
53 #include <Xm/Text.h>
54 #include <Xm/ToggleB.h>
55 
56 
57 #include "System.h"
58 #include "LstLinked.h"
59 #include "Message.h"
60 #include "TimDate.h"
61 
62 #include "msgXdiary.h"
63 #include "xtmGlobal.h"
64 #include "xtmCustBase.h"
65 #include "xtmDbTools.h"
66 #include "xtmFields.h"
67 #include "xtmFormat.h"
68 #include "xtmGroupDb.h"
69 #include "xtmHelp.h"
70 #include "xtmIcons.h"
71 #include "xtmLocate.h"
72 #include "xtmMsgBase.h"
73 #include "xtmTools.h"
74 #include "xitError.h"
75 #include "xitFieldSel.h"
76 #include "xitTools.h"
77 #include "XmUbTimeB.h"
78 #include "xtmMsgSend.h"
79 #include "xtmDbMisc.h"
80 
81 
82 /*----------------------------------------------------------------------------
83 --  Macro definitions
84 ----------------------------------------------------------------------------*/
85 
86 /* Local widgets in the recipients window. */
87 #define dbLa                dataLocalW[  0 ]
88 #define dbLi                dataLocalW[  1 ]
89 #define genInfoLa           dataLocalW[  2 ]
90 #define groupLa             dataLocalW[  3 ]
91 #define groupLi             dataLocalW[  4 ]
92 #define ho1Sp               dataLocalW[  5 ]
93 #define menuBr              dataLocalW[  6 ]
94 #define nextInfoLa          dataLocalW[  7 ]
95 #define srcActionRc         dataLocalW[  8 ]
96 #define toActionRc          dataLocalW[  9 ]
97 #define toFieldLa           dataLocalW[ 10 ]
98 #define toFieldRc           dataLocalW[ 11 ]
99 #define toFieldTx           dataLocalW[ 12 ]
100 #define toLa                dataLocalW[ 13 ]
101 #define toLi                dataLocalW[ 14 ]
102 
103 
104 /* Local widgets in the message window. */
105 #define dateEntTb           dataLocalW[  0 ]
106 #define dateEntLa           dataLocalW[  1 ]
107 #define durEntFs            dataLocalW[  2 ]
108 #define durEntLa            dataLocalW[  3 ]
109 #define flagsRc             dataLocalW[  4 ]
110 #define mailFailTb          dataLocalW[  5 ]
111 #define msgMenuBr           dataLocalW[  6 ]
112 #define messageLa           dataLocalW[  7 ]
113 #define msgTx               dataLocalW[  8 ]
114 #define onlyMailTb          dataLocalW[  9 ]
115 #define startEntTb          dataLocalW[ 10 ]
116 #define startEntLa          dataLocalW[ 11 ]
117 #define textLa              dataLocalW[ 12 ]
118 #define textTx              dataLocalW[ 13 ]
119 #define timeEntFr           dataLocalW[ 14 ]
120 #define timeEntRc           dataLocalW[ 15 ]
121 
122 
123 /*----------------------------------------------------------------------------
124 --  Type declarations
125 ----------------------------------------------------------------------------*/
126 
127 /* Record describing one instance of the send window. */
128 typedef struct {
129 
130   /* Any entry added in the message window? */
131   Boolean  entry_added;
132 
133   /* Entry selected in the to list. */
134   int  to_list_entry;
135 
136   /* Entry ID to send. */
137   UINT32  entry_id;
138 
139   /* Entry ID to send comes from DB? */
140   char  db_name[ XTM_GL_MAX_CAL_NAME + 1 ];
141 
142   /* File selection window. */
143   Widget  fileSelectW;
144 
145   /* The message window. */
146   Widget  messageW;
147 
148   /* The recipients window. */
149   Widget  recipientW;
150 
151   /* Default date for appointment. */
152   TIM_TIME_REF  default_entry_date;
153 
154   /* Application wide data. */
155   XTM_GL_BASE_DATA_REF  appl_data_ref;
156 
157 } SEND_REC, *SEND_REC_REF;
158 
159 
160 /*----------------------------------------------------------------------------
161 --  Global definitions
162 ----------------------------------------------------------------------------*/
163 
164 /* Name of module. */
165 static char  *module_name = "xtmMsgSend";
166 
167 /* IDs for the help windows. */
168 static char  *send_window_id = "MsgSend";
169 
170 
171 /*----------------------------------------------------------------------------
172 --  Function prototypes
173 ----------------------------------------------------------------------------*/
174 
175 static void
176   addFromListCB( Widget                widget,
177                  SEND_REC_REF          send_ref,
178                  XmListCallbackStruct  *call_data );
179 
180 static void
181   clearToCB( Widget        widget,
182              SEND_REC_REF  send_ref,
183              XtPointer     call_data );
184 
185 static void
186   closeCB( Widget        widget,
187            SEND_REC_REF  send_ref,
188            XtPointer     call_data );
189 
190 static Widget
191   createMessageWindow( Widget        parent,
192                        SEND_REC_REF  send_ref );
193 
194 static Widget
195   createRecipientWindow( Widget        parent,
196                          SEND_REC_REF  send_ref );
197 
198 static void
199   deleteToCB( Widget        widget,
200               SEND_REC_REF  send_ref,
201               XtPointer     call_data );
202 
203 static void
204   destroyCB( Widget        widget,
205              SEND_REC_REF  send_ref,
206              XtPointer     call_data );
207 
208 static void
209   doAddRecipientsCB( Widget        widget,
210                      SEND_REC_REF  send_ref,
211                      XtPointer     call_data );
212 
213 static void
214   includeFileCB( Widget        widget,
215                  SEND_REC_REF  send_ref,
216                  XtPointer     call_data );
217 
218 static void
219   includeFileActionCB( XIT_FILE_SEL_REASON  reason,
220                        char                 *file_name,
221                        void                 *user_data );
222 
223 static void
224   infoCB( Widget                     widget,
225           SEND_REC_REF               send_ref,
226           XmRowColumnCallbackStruct  *call_data );
227 
228 static void
229   messageCB( Widget        widget,
230              SEND_REC_REF  send_ref,
231              XtPointer     call_data );
232 
233 static void
234   msgCloseCB( Widget        widget,
235               SEND_REC_REF  send_ref,
236               XtPointer     call_data );
237 
238 static void
239   sendCB( Widget        widget,
240           SEND_REC_REF  send_ref,
241           XtPointer     call_data );
242 
243 static void
244   setMessageWindowValues( SEND_REC_REF  send_ref,
245                           char          *db_name,
246                           UINT32        id );
247 
248 static void
249   setRecipientWindowValues( SEND_REC_REF  send_ref );
250 
251 static void
252   toListCB( Widget                widget,
253             SEND_REC_REF          send_ref,
254             XmListCallbackStruct  *call_data );
255 
256 
257 
258 /*----------------------------------------------------------------------------
259 --  Functions
260 ----------------------------------------------------------------------------*/
261 
262 XTM_MS_HANDLE
xtmMsInitialize(XTM_GL_BASE_DATA_REF appl_data_ref,Widget parent)263   xtmMsInitialize( XTM_GL_BASE_DATA_REF  appl_data_ref,
264                    Widget                parent )
265 {
266 
267   /* Variables. */
268   SEND_REC_REF  send_ref;
269 
270 
271   /* Code. */
272 
273   /* Create and initialize our private data. */
274   send_ref = SysNew( SEND_REC );
275   if( send_ref == NULL )
276     return( NULL );
277 
278   send_ref -> appl_data_ref = appl_data_ref;
279   send_ref -> entry_added   = False;
280   send_ref -> fileSelectW   = NULL;
281   send_ref -> messageW      = NULL;
282   send_ref -> recipientW    = NULL;
283   send_ref -> entry_id      = 0;
284   send_ref -> db_name[ 0 ]  = '\0';
285 
286   /* Create the message recipients window. */
287   send_ref -> recipientW = createRecipientWindow( parent, send_ref );
288   if( send_ref -> recipientW == NULL ) {
289     SysFree( send_ref );
290 
291     return( NULL );
292   }
293 
294 
295   return( (XTM_MS_HANDLE) send_ref );
296 
297 } /* xtmMsInitialize */
298 
299 
300 /*----------------------------------------------------------------------*/
301 
302 void
xtmMsDestroy(XTM_MS_HANDLE send_handle)303   xtmMsDestroy( XTM_MS_HANDLE  send_handle )
304 {
305 
306   /* Variables. */
307   SEND_REC_REF  send_ref;
308 
309 
310   /* Code. */
311 
312   if( send_handle == NULL )
313     return;
314 
315   /* Our private data. */
316   send_ref = (SEND_REC_REF) send_handle;
317 
318 
319   /* Get rid of all windows. */
320   if( send_ref -> recipientW != NULL )
321     XtDestroyWidget( send_ref -> recipientW );
322 
323 
324   return;
325 
326 } /* xtmMsDestroy */
327 
328 
329 /*---------------------------------------------------------------------------*/
330 
331 void
xtmMsSendMessage(XTM_MS_HANDLE send_handle,char * db_name,UINT32 id)332   xtmMsSendMessage( XTM_MS_HANDLE  send_handle,
333                     char           *db_name,
334                     UINT32         id )
335 {
336 
337   /* Variables. */
338   Arg           args[ 5 ];
339   Cardinal      n;
340   SEND_REC_REF  send_ref;
341 
342 
343   /* Code. */
344 
345   /* Our private data. */
346   send_ref = (SEND_REC_REF) send_handle;
347 
348   send_ref -> entry_added        = False;
349   send_ref -> entry_id           = id;
350   send_ref -> default_entry_date = (TIM_TIME_REF) 0;
351 
352   strcpy( send_ref -> db_name, db_name );
353 
354 
355   /* Set the values in the recipient window. */
356   setRecipientWindowValues( send_ref );
357 
358 
359   /* Make sure the message window is visible. */
360   XtPopup( send_ref -> recipientW, XtGrabNone );
361 
362   XRaiseWindow( XtDisplay( send_ref -> recipientW ),
363                 XtWindow(  send_ref -> recipientW ) );
364 
365   XtMapWidget( send_ref -> recipientW );
366 
367 
368   /* Make sure our children don't spoil our size. */
369   n = 0;
370   XtSetArg( args[ n ], XmNallowShellResize, False ); n++;
371   XtSetValues( send_ref -> recipientW, args, n );
372 
373 
374   return;
375 
376 } /* xtmMsSendMessage */
377 
378 
379 /*---------------------------------------------------------------------------*/
380 
381 void
xtmMsSetRecipients(XTM_MS_HANDLE send_handle,char * msg_to[],int msg_to_no)382   xtmMsSetRecipients( XTM_MS_HANDLE  send_handle,
383                       char           *msg_to[],
384                       int            msg_to_no )
385 {
386 
387   /* Variables. */
388   int           index;
389   int           index1;
390   Arg           args[ 5 ];
391   Cardinal      n;
392   Widget        mainW;
393   Widget        tempW;
394   XmString      list_items[ 500 ];
395   SEND_REC_REF  send_ref;
396 
397 
398   /* Code. */
399 
400   /* Our private data. */
401   send_ref = (SEND_REC_REF) send_handle;
402 
403   if( send_ref == NULL )
404     return;
405 
406   mainW = XtNameToWidget( send_ref -> recipientW,
407                           "MsgSendTlBase.MsgSendTlFo" );
408 
409 
410   /* Assign all recipients to the list. */
411   if( msg_to_no > 500 )
412     msg_to_no = 500;
413 
414   for( index = 0; index < msg_to_no; index++ )
415     list_items[ index ] = XmStringCreate( msg_to[ index ], CS );
416 
417   tempW = XtNameToWidget( mainW, "ToLiSW.ToLi" );
418 
419   n = 0;
420   XtSetArg( args[ n ], XmNitems, list_items ); n++;
421   XtSetArg( args[ n ], XmNitemCount, index ); n++;
422   XtSetValues( tempW, args, n );
423 
424   /* Free allocated memory. */
425   for( index1 = 0; index1 < index; index1++ )
426     XmStringFree( list_items[ index1 ] );
427 
428 
429   return;
430 
431 } /* xtmMsSetRecipients */
432 
433 
434 /*---------------------------------------------------------------------------*/
435 
436 void
xtmMsSetToDate(XTM_MS_HANDLE send_handle,TIM_TIME_REF to_date)437   xtmMsSetToDate( XTM_MS_HANDLE  send_handle,
438                   TIM_TIME_REF   to_date )
439 {
440 
441   /* Variables. */
442   SEND_REC_REF  send_ref;
443 
444 
445   /* Code. */
446 
447   /* Our private data. */
448   send_ref = (SEND_REC_REF) send_handle;
449 
450   if( send_ref == NULL )
451     return;
452 
453   send_ref -> default_entry_date = to_date;
454 
455 
456   return;
457 
458 } /* xtmMsSetToDate */
459 
460 
461 /*----------------------------------------------------------------------*/
462 
463 static Widget
createMessageWindow(Widget parent,SEND_REC_REF send_ref)464   createMessageWindow( Widget        parent,
465                        SEND_REC_REF  send_ref )
466 {
467 
468   /* Variables. */
469   int                     index;
470   char                    *char_ref;
471   Arg                     args[ 10 ];
472   Cardinal                n;
473   Widget                  dataLocalW[ 16 ];
474   Widget                  menuCasc[ 2 ];
475   Widget                  menuFileBu[ 3 ];
476   Widget                  menuHelpBu[ 6 ];
477   Widget                  msgFd;
478   Widget                  pulldownMenu[ 2 ];
479   Widget                  tempW;
480   Widget                  workFo;
481   XTM_GL_BASE_DATA_REF    appl_data_ref;
482   XTM_GL_CUSTOM_DATA_REF  custom_data_ref;
483 
484   static char  def_durations[] =
485     "0:10 0:15 0:30 0:45 1:00 1:30 2:00 4:00 6:00";
486 
487   static char  *pull_downs[] = { "pdown1", "pdown2" };
488 
489   static XIT_TEXT_STRUCT text_buffer_def[] = {
490     { "MsgTx",  NULL, 2, True },
491     { "TextTx", NULL, 2, True },
492   };
493 
494   static XIT_CASCADE_STRUCT menupane[] = {
495     { "", "", "FilePane" },
496     { "", "", "HelpPane" },
497   };
498 
499   static XIT_MENU_BUTTON_STRUCT file_casc[] = {
500     { "",      "",  NULL, "IncludeBu", True,  False, False },
501     { XIT_SEP, " ", NULL, "",          False, False, False },
502     { "",      "",  NULL, "CloseBu",   True,  False, False },
503   };
504 
505   static XIT_MENU_BUTTON_STRUCT help_casc[] = {
506     { "", "", NULL, "ContextBu", True, False, False },
507     { "", "", NULL, "WindowsBu", True, False, False },
508     { "", "", NULL, "KeysBu",    True, False, False },
509     { "", "", NULL, "IndexBu",   True, False, False },
510     { "", "", NULL, "HelpBu",    True, False, False },
511     { "", "", NULL, "VersionBu", True, False, False },
512   };
513 
514   static XIT_ACTION_AREA_ITEM  action_buttons[] = {
515     { "",   sendCB,     NULL },
516     { NULL, NULL,       NULL },
517     { NULL, NULL,       NULL },
518     { "",   msgCloseCB, NULL },
519   };
520 
521 
522   /* Code. */
523 
524   appl_data_ref   = send_ref -> appl_data_ref;
525   custom_data_ref = appl_data_ref -> custom_data;
526 
527   /* Initialize the menu items. */
528   action_buttons[ 0 ].label = msgGetText( MXDI_SEND_BUTTON );
529   action_buttons[ 0 ].data  = send_ref;
530   action_buttons[ 3 ].label = msgGetText( MXDI_CLOSE_BUTTON );
531   action_buttons[ 3 ].data  = send_ref;
532 
533   menupane[ 0 ].title    = msgGetText( MXDI_FILE_MENU );
534   menupane[ 0 ].mnemonic = msgGetText( MXDI_FILE_MENU_ACC );
535   menupane[ 1 ].title    = msgGetText( MXDI_HELP_MENU );
536   menupane[ 1 ].mnemonic = msgGetText( MXDI_HELP_MENU_ACC );
537 
538   file_casc[ 0 ].title    = msgGetText( MXDI_INCL_FILE_MENU );
539   file_casc[ 0 ].mnemonic = msgGetText( MXDI_INCL_FILE_MENU_ACC );
540   file_casc[ 2 ].title    = msgGetText( MXDI_CLOSE_MENU );
541   file_casc[ 2 ].mnemonic = msgGetText( MXDI_CLOSE_MENU_ACC );
542 
543   help_casc[ 0 ].title    = msgGetText( MXDI_HELP_CONTEXT );
544   help_casc[ 0 ].mnemonic = msgGetText( MXDI_HELP_CONTEXT_ACC );
545   help_casc[ 1 ].title    = msgGetText( MXDI_HELP_WINDOWS );
546   help_casc[ 1 ].mnemonic = msgGetText( MXDI_HELP_WINDOWS_ACC );
547   help_casc[ 2 ].title    = msgGetText( MXDI_HELP_KEYS );
548   help_casc[ 2 ].mnemonic = msgGetText( MXDI_HELP_KEYS_ACC );
549   help_casc[ 3 ].title    = msgGetText( MXDI_HELP_INDEX );
550   help_casc[ 3 ].mnemonic = msgGetText( MXDI_HELP_INDEX_ACC );
551   help_casc[ 4 ].title    = msgGetText( MXDI_HELP_HELP );
552   help_casc[ 4 ].mnemonic = msgGetText( MXDI_HELP_HELP_ACC );
553   help_casc[ 5 ].title    = msgGetText( MXDI_HELP_VERSION );
554   help_casc[ 5 ].mnemonic = msgGetText( MXDI_HELP_VERSION_ACC );
555 
556 
557   /* Create a form dialog with buttons. */
558   msgFd = xitCreateFormDialog( parent, "MsgFd",
559                                1, 0,
560                                action_buttons,
561                                XtNumber( action_buttons ) );
562 
563   char_ref = msgGetText( MXDI_COMPOSE_MSG_TITLE );
564 
565   n = 0;
566   XtSetArg( args[ n ], XmNtitle, char_ref ); n++;
567   XtSetValues( XtParent( msgFd ), args, n );
568 
569 
570   /* Use this form as a working form. */
571   workFo = XtNameToWidget( msgFd, "MsgFdFo" );
572 
573 
574   /* Create the menubar and menu cascades. */
575   msgMenuBr = XmCreateMenuBar( workFo, "MsgMenuBr", args, 0 );
576 
577   n = 0;
578   for( index = 0; index < XtNumber( pulldownMenu ); index++ )
579     pulldownMenu[ index ] = XmCreatePulldownMenu( msgMenuBr,
580                                                   pull_downs[ index ],
581                                                   NULL, n );
582 
583   for( index = 0; index < XtNumber( menuCasc ); index++ )
584     menuCasc[ index ] = xitCreateCascadeButton( msgMenuBr,
585                                                 pulldownMenu[ index ],
586                                                 &menupane[ index ] );
587 
588   /* The help button should be placed to the right. */
589   index = XtNumber( menuCasc ) - 1;
590   n     = 0;
591   XtSetArg( args[ n ], XmNmenuHelpWidget, menuCasc[ index ] ); n++;
592   XtSetValues( menuBr, args, n );
593 
594 
595   /* Create the file menu. */
596   for( index = 0; index < XtNumber( menuFileBu ); index++ )
597     menuFileBu[ index ] = xitCreateMenuPushButton( pulldownMenu[ 0 ],
598                                                    &file_casc[ index ] );
599   XtAddCallback( menuFileBu[ 0 ], XmNactivateCallback,
600                  (XtCallbackProc) includeFileCB, (XtPointer) send_ref );
601   XtAddCallback( menuFileBu[ 2 ], XmNactivateCallback,
602                  (XtCallbackProc) msgCloseCB, (XtPointer) send_ref );
603 
604 
605   /* Create the help menu. */
606   XtAddCallback( pulldownMenu[ 1 ], XmNentryCallback,
607                  (XtCallbackProc) infoCB, (XtPointer) send_ref );
608 
609   for( index = 0; index < XtNumber( menuHelpBu ); index++ ) {
610     menuHelpBu[ index ] = xitCreateMenuPushButton( pulldownMenu[ 1 ],
611                                                    &help_casc[ index ] );
612 
613     XtAddCallback( menuHelpBu[ index ], XmNactivateCallback,
614                    (XtCallbackProc) infoCB, (XtPointer)(intptr_t)index );
615   }
616 
617   /* We can't do context sensitive help. */
618   XtSetSensitive( menuHelpBu[ 0 ], False );
619 
620 
621   /* Create the time entry form. */
622   timeEntFr = XmCreateFrame( workFo, "TimeEntFr", args, 0 );
623 
624   n = 0;
625   XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL  ); n++;
626   XtSetArg( args[ n ], XmNpacking,     XmPACK_COLUMN ); n++;
627   XtSetArg( args[ n ], XmNnumColumns,  3             ); n++;
628   timeEntRc = XmCreateRowColumn( timeEntFr, "TimeEntRc", args, n );
629 
630 
631   /* Entry date. */
632   dateEntLa = xitCreateLabel( timeEntRc, "DateEntLa",
633                               msgGetText( MXDI_DATE_LABEL ), -1 );
634 
635   dateEntTb = xtmFlCreateDateField( timeEntRc, "DateEntTb" );
636 
637 
638   /* Start time. */
639   startEntLa = xitCreateLabel( timeEntRc, "StartEntLa",
640                                msgGetText( MXDI_ENTRY_START_LABEL ), -1 );
641 
642   startEntTb = xtmFlCreateTimeField( timeEntRc, "StartEntTb" );
643 
644 
645   /* Duration. */
646   durEntLa = xitCreateLabel( timeEntRc, "DurEntLa",
647                              msgGetText( MXDI_ENTRY_DURATION_LABEL ), -1 );
648 
649   durEntFs = xtmFlCreateSelField( timeEntRc, "DurEntFs",
650                                   5, def_durations,
651                                   ' ', True,
652                                   NULL, NULL );
653 
654   tempW = xitFieldSelectGetChild( durEntFs, xitFIELD_SELECT_TEXT_FIELD );
655 
656 
657   /* Create the flags form. */
658   n = 0;
659   XtSetArg( args[ n ], XmNorientation, XmVERTICAL ); n++;
660   flagsRc = XmCreateRowColumn( workFo, "FlagsRc", args, n );
661 
662   onlyMailTb = xitCreateToggleButton(
663                  flagsRc, "OnlyMailTb",
664                  msgGetText( MXDI_ONLY_MAIL_LABEL ), False );
665 
666   mailFailTb = xitCreateToggleButton(
667                  flagsRc, "MailFailTb",
668                  msgGetText( MXDI_MAIL_IF_FAIL_LABEL ), True );
669 
670 
671   /* Appointment text label. */
672   textLa = xitCreateLabel( workFo, "TextLa",
673                            msgGetText( MXDI_TEXT_LABEL ), -1 );
674 
675   textTx = xitCreateTextScrolled( workFo, &text_buffer_def[ 1 ] );
676 
677   XtOverrideTranslations( textTx, xtm_di_newline_trans );
678 
679 
680   /* Attached remark text. */
681   messageLa = xitCreateLabel( workFo, "MessageLa",
682                               msgGetText( MXDI_REMARK_LABEL ), -1 );
683 
684   msgTx = xitCreateTextScrolled( workFo, &text_buffer_def[ 0 ] );
685 
686   XtOverrideTranslations( msgTx, xtm_di_newline_trans );
687 
688   n = 0;
689   XtSetArg( args[ n ], XmNmaxLength, 160 ); n++;
690   XtSetValues( msgTx, args, n );
691 
692 
693   /* Place the main elements together. */
694   xitAttachWidget( msgMenuBr,
695                    XmATTACH_FORM, NULL, XmATTACH_FORM, NULL,
696                    XmATTACH_FORM, NULL, XmATTACH_NONE, NULL );
697   xitAttachWidget( timeEntFr,
698                    XmATTACH_WIDGET, msgMenuBr, XmATTACH_FORM, NULL,
699                    XmATTACH_NONE,   NULL,      XmATTACH_NONE, NULL );
700   xitAttachWidget( flagsRc,
701                    XmATTACH_WIDGET, msgMenuBr, XmATTACH_WIDGET, timeEntFr,
702                    XmATTACH_NONE,   NULL,      XmATTACH_NONE, NULL );
703   xitAttachWidget( textLa,
704                    XmATTACH_WIDGET, timeEntFr, XmATTACH_FORM, NULL,
705                    XmATTACH_NONE,   NULL,      XmATTACH_NONE, NULL );
706   xitAttachWidget( XtParent( textTx ),
707                    XmATTACH_WIDGET, textLa, XmATTACH_FORM, NULL,
708                    XmATTACH_NONE,   NULL,   XmATTACH_NONE, NULL );
709   xitAttachWidget( messageLa,
710                    XmATTACH_WIDGET, XtParent( textTx ), XmATTACH_FORM, NULL,
711                    XmATTACH_NONE,   NULL,               XmATTACH_NONE, NULL );
712   xitAttachWidget( XtParent( msgTx ),
713                    XmATTACH_WIDGET, messageLa, XmATTACH_FORM, NULL,
714                    XmATTACH_NONE,   NULL,      XmATTACH_NONE, NULL );
715 
716 
717   /* Make sure there is enough space between the children. */
718   n = 0;
719   XtSetArg( args[ n ], XmNtopOffset,    5 ); n++;
720   XtSetArg( args[ n ], XmNleftOffset,   5 ); n++;
721   XtSetArg( args[ n ], XmNrightOffset,  5 ); n++;
722   XtSetArg( args[ n ], XmNbottomOffset, 5 ); n++;
723   XtSetValues( flagsRc,             args, n );
724   XtSetValues( messageLa,           args, n );
725   XtSetValues( XtParent( msgTx ),   args, n );
726   XtSetValues( timeEntFr,           args, n );
727   XtSetValues( textLa,              args, n );
728   XtSetValues( XtParent( textTx ),  args, n );
729 
730 
731   /* Manage all the children. */
732   XtManageChildren( menuCasc,   XtNumber( menuCasc ) );
733   XtManageChildren( menuHelpBu, XtNumber( menuHelpBu ) );
734   XtManageChildren( menuFileBu, XtNumber( menuFileBu ) );
735 
736   xitManageChildren( dataLocalW, XtNumber( dataLocalW ) );
737 
738 
739   /* Set the size of the window. */
740   xitSetSizeFormDialog( msgFd, True );
741 
742 
743   /* Make the final attachments. */
744   xitAttachWidget( XtParent( msgTx ),
745                    XmATTACH_NONE, NULL, XmATTACH_FORM, NULL,
746                    XmATTACH_FORM, NULL, XmATTACH_FORM, NULL );
747   xitAttachWidget( messageLa,
748                    XmATTACH_NONE, NULL, XmATTACH_FORM, NULL,
749                    XmATTACH_NONE, NULL, XmATTACH_WIDGET, XtParent( msgTx ) );
750   xitAttachWidget( XtParent( textTx ),
751                    XmATTACH_WIDGET, textLa, XmATTACH_FORM,   NULL,
752                    XmATTACH_FORM,   NULL,   XmATTACH_WIDGET, messageLa );
753 
754 
755   return( msgFd );
756 
757 } /* createMessageWindow */
758 
759 
760 /*----------------------------------------------------------------------*/
761 
762 static Widget
createRecipientWindow(Widget parent,SEND_REC_REF send_ref)763   createRecipientWindow( Widget        parent,
764                          SEND_REC_REF  send_ref )
765 {
766 
767   /* Variables. */
768   int                     index;
769   char                    *char_ref;
770   Arg                     args[ 10 ];
771   Cardinal                n;
772   Widget                  dataLocalW[ 15 ];
773   Widget                  menuCasc[ 2 ];
774   Widget                  menuFileBu[ 1 ];
775   Widget                  menuHelpBu[ 6 ];
776   Widget                  msgSendTl;
777   Widget                  pulldownMenu[ 2 ];
778   Widget                  srcActionBu[ 1 ];
779   Widget                  toplevel;
780   Widget                  toActionBu[ 2 ];
781   Widget                  workFo;
782   XTM_GL_BASE_DATA_REF    appl_data_ref;
783   XTM_GL_CUSTOM_DATA_REF  custom_data_ref;
784 
785   static char  *pull_downs[] = { "pdown1", "pdown2" };
786 
787   static XIT_TEXT_STRUCT text_buffer_def[] = {
788     { "ToFieldTx", NULL, 1, True },
789   };
790 
791   static XIT_CASCADE_STRUCT menupane[] = {
792     { "", "", "FilePane" },
793     { "", "", "HelpPane" },
794   };
795 
796   static XIT_MENU_BUTTON_STRUCT file_casc[] = {
797     { "", "", NULL, "CloseBu", True, False, False },
798   };
799 
800   static XIT_MENU_BUTTON_STRUCT help_casc[] = {
801     { "", "", NULL, "ContextBu", True, False, False },
802     { "", "", NULL, "WindowsBu", True, False, False },
803     { "", "", NULL, "KeysBu",    True, False, False },
804     { "", "", NULL, "IndexBu",   True, False, False },
805     { "", "", NULL, "HelpBu",    True, False, False },
806     { "", "", NULL, "VersionBu", True, False, False },
807   };
808 
809   static XIT_PUSH_STRUCT source_action_def[] = {
810     { "AddPb", "", "", True, NULL },
811   };
812 
813   static XIT_PUSH_STRUCT to_action_def[] = {
814     { "DeletePb", "", "", True, NULL },
815     { "ClearPb",  "", "", True, NULL },
816   };
817 
818   static XIT_ACTION_AREA_ITEM  action_buttons[] = {
819     { "",   messageCB, NULL },
820     { NULL, NULL,      NULL },
821     { NULL, NULL,      NULL },
822     { "",   closeCB,   NULL },
823   };
824 
825 
826   /* Code. */
827 
828   appl_data_ref   = send_ref -> appl_data_ref;
829   custom_data_ref = appl_data_ref -> custom_data;
830 
831   /* Initialize the menu items. */
832   action_buttons[ 0 ].label = msgGetText( MXDI_COMPOSE_MESSAGE_BUTTON );
833   action_buttons[ 0 ].data  = send_ref;
834   action_buttons[ 3 ].label = msgGetText( MXDI_CLOSE_BUTTON );
835   action_buttons[ 3 ].data  = send_ref;
836 
837   menupane[ 0 ].title    = msgGetText( MXDI_FILE_MENU );
838   menupane[ 0 ].mnemonic = msgGetText( MXDI_FILE_MENU_ACC );
839   menupane[ 1 ].title    = msgGetText( MXDI_HELP_MENU );
840   menupane[ 1 ].mnemonic = msgGetText( MXDI_HELP_MENU_ACC );
841 
842   file_casc[ 0 ].title    = msgGetText( MXDI_CLOSE_MENU );
843   file_casc[ 0 ].mnemonic = msgGetText( MXDI_CLOSE_MENU_ACC );
844 
845   help_casc[ 0 ].title    = msgGetText( MXDI_HELP_CONTEXT );
846   help_casc[ 0 ].mnemonic = msgGetText( MXDI_HELP_CONTEXT_ACC );
847   help_casc[ 1 ].title    = msgGetText( MXDI_HELP_WINDOWS );
848   help_casc[ 1 ].mnemonic = msgGetText( MXDI_HELP_WINDOWS_ACC );
849   help_casc[ 2 ].title    = msgGetText( MXDI_HELP_KEYS );
850   help_casc[ 2 ].mnemonic = msgGetText( MXDI_HELP_KEYS_ACC );
851   help_casc[ 3 ].title    = msgGetText( MXDI_HELP_INDEX );
852   help_casc[ 3 ].mnemonic = msgGetText( MXDI_HELP_INDEX_ACC );
853   help_casc[ 4 ].title    = msgGetText( MXDI_HELP_HELP );
854   help_casc[ 4 ].mnemonic = msgGetText( MXDI_HELP_HELP_ACC );
855   help_casc[ 5 ].title    = msgGetText( MXDI_HELP_VERSION );
856   help_casc[ 5 ].mnemonic = msgGetText( MXDI_HELP_VERSION_ACC );
857 
858   source_action_def[ 0 ].title = msgGetText( MXDI_MSG_ADD_RECIPIENT );
859   to_action_def[ 0 ].title     = msgGetText( MXDI_DELETE_ITEM );
860   to_action_def[ 1 ].title     = msgGetText( MXDI_CLEAR_BUTTON );
861 
862 
863   /* Create a separate window. */
864   toplevel = xitGetToplevelWidget( parent );
865 
866   msgSendTl = xitCreateToplevelDialog( toplevel, "MsgSendTl",
867                                        1, 0,
868                                        action_buttons,
869                                        XtNumber( action_buttons ) );
870 
871   char_ref = msgGetText( MXDI_RECIPIENT_MSG_TITLE );
872 
873   n = 0;
874   XtSetArg( args[ n ], XmNtitle, char_ref ); n++;
875   XtSetValues( msgSendTl, args, n );
876 
877   char_ref = msgGetText( MXDI_SEND_MSG_IC_TITLE );
878 
879   n = 0;
880   XtSetArg( args[ n ], XmNiconName, char_ref ); n++;
881   XtSetValues( msgSendTl, args, n );
882 
883   XtAddCallback( msgSendTl, XmNdestroyCallback,
884                  (XtCallbackProc) destroyCB, (XtPointer) send_ref );
885 
886 
887   /* Exit from message send if this window is deleted. */
888   {
889     Atom  wm_delete_window;
890 
891     wm_delete_window = XmInternAtom( XtDisplay( msgSendTl ),
892                                      "WM_DELETE_WINDOW", False );
893 
894     XmAddWMProtocols(        msgSendTl, &wm_delete_window, 1 );
895     XmAddWMProtocolCallback( msgSendTl, wm_delete_window,
896                              (XtCallbackProc) closeCB, (XtPointer) send_ref );
897   } /* block */
898 
899 
900   /* Use this form as a working form. */
901   workFo = XtNameToWidget( msgSendTl, "MsgSendTlBase.MsgSendTlFo" );
902 
903 
904   /* Create the menubar and menu cascades. */
905   menuBr = XmCreateMenuBar( workFo, "MenuBr", args, 0 );
906 
907   n = 0;
908   for( index = 0; index < XtNumber( pulldownMenu ); index++ )
909     pulldownMenu[ index ] = XmCreatePulldownMenu( menuBr,
910                                                   pull_downs[ index ],
911                                                   NULL, n );
912 
913   for( index = 0; index < XtNumber( menuCasc ); index++ )
914     menuCasc[ index ] = xitCreateCascadeButton( menuBr,
915                                                 pulldownMenu[ index ],
916                                                 &menupane[ index ] );
917 
918   /* The help button should be placed to the right. */
919   index = XtNumber( menuCasc ) - 1;
920   n     = 0;
921   XtSetArg( args[ n ], XmNmenuHelpWidget, menuCasc[ index ] ); n++;
922   XtSetValues( menuBr, args, n );
923 
924 
925   /* Create the file menu. */
926   for( index = 0; index < XtNumber( menuFileBu ); index++ )
927     menuFileBu[ index ] = xitCreateMenuPushButton( pulldownMenu[ 0 ],
928                                                    &file_casc[ index ] );
929   XtAddCallback( menuFileBu[ 0 ], XmNactivateCallback,
930                  (XtCallbackProc) closeCB, (XtPointer) send_ref );
931 
932 
933   /* Create the help menu. */
934   XtAddCallback( pulldownMenu[ 1 ], XmNentryCallback,
935                  (XtCallbackProc) infoCB, (XtPointer) send_ref );
936 
937   for( index = 0; index < XtNumber( menuHelpBu ); index++ ) {
938     menuHelpBu[ index ] = xitCreateMenuPushButton( pulldownMenu[ 1 ],
939                                                    &help_casc[ index ] );
940 
941     XtAddCallback( menuHelpBu[ index ], XmNactivateCallback,
942                    (XtCallbackProc) infoCB, (XtPointer)(intptr_t)index );
943   }
944 
945   /* We can't do context sensitive help. */
946   XtSetSensitive( menuHelpBu[ 0 ], False );
947 
948 
949   /* General help text. */
950   genInfoLa = xitCreateLabel( workFo, "GenInfoLa",
951                               msgGetText( MXDI_MSG_INFO_LABEL ), -1 );
952 
953   /* Create the to user list. */
954   toLa = xitCreateLabel( workFo, "ToLa", msgGetText( MXDI_MSG_TO_LABEL ), -1 );
955 
956   n = 0;
957   XtSetArg( args[ n ], XmNlistSizePolicy,         XmCONSTANT ); n++;
958   XtSetArg( args[ n ], XmNscrollBarDisplayPolicy, XmSTATIC ); n++;
959   XtSetArg( args[ n ], XmNselectionPolicy,        XmSINGLE_SELECT ); n++;
960   XtSetArg( args[ n ], XmNlistMarginHeight,       5 ); n++;
961   XtSetArg( args[ n ], XmNlistMarginWidth,        5 ); n++;
962   toLi = XmCreateScrolledList( workFo, "ToLi", args, n );
963 
964   XtAddCallback( toLi, XmNsingleSelectionCallback,
965                  (XtCallbackProc) toListCB, (XtPointer) send_ref );
966 
967 
968   /* Delete or clear recipients. */
969   n = 0;
970   XtSetArg( args[ n ], XmNorientation,  XmHORIZONTAL ); n++;
971   XtSetArg( args[ n ], XmNspacing,      10 ); n++;
972   XtSetArg( args[ n ], XmNmarginHeight, 10 ); n++;
973   toActionRc = XmCreateRowColumn( workFo, "ToActionRc", args, n );
974 
975   for( index = 0; index < XtNumber( to_action_def ); index++ )
976     toActionBu[ index ] = xitCreatePushButton(
977                             toActionRc, &to_action_def[ index ] );
978 
979   XtAddCallback( toActionBu[ 0 ], XmNactivateCallback,
980                  (XtCallbackProc) deleteToCB, (XtPointer) send_ref );
981   XtAddCallback( toActionBu[ 1 ], XmNactivateCallback,
982                  (XtCallbackProc) clearToCB, (XtPointer) send_ref );
983 
984 
985   /* Create calendar list. */
986   dbLa = xitCreateLabel( workFo, "DbLa",
987                          msgGetText( MXDI_MSG_DB_LIST_LABEL ), -1 );
988 
989   n = 0;
990   XtSetArg( args[ n ], XmNlistSizePolicy,         XmCONSTANT ); n++;
991   XtSetArg( args[ n ], XmNscrollBarDisplayPolicy, XmSTATIC ); n++;
992   XtSetArg( args[ n ], XmNselectionPolicy,        XmSINGLE_SELECT ); n++;
993   XtSetArg( args[ n ], XmNlistMarginHeight,       5 ); n++;
994   XtSetArg( args[ n ], XmNlistMarginWidth,        5 ); n++;
995   dbLi = XmCreateScrolledList( workFo, "DbLi", args, n );
996 
997   XtAddCallback( dbLi, XmNdefaultActionCallback,
998                  (XtCallbackProc) addFromListCB, (XtPointer) send_ref );
999 
1000 
1001 
1002   /* Create the group list. */
1003   groupLa = xitCreateLabel( workFo, "GroupLa",
1004                             msgGetText( MXDI_MSG_GROUP_LIST_LABEL ), -1 );
1005 
1006   n = 0;
1007   XtSetArg( args[ n ], XmNlistSizePolicy,         XmCONSTANT ); n++;
1008   XtSetArg( args[ n ], XmNscrollBarDisplayPolicy, XmSTATIC ); n++;
1009   XtSetArg( args[ n ], XmNselectionPolicy,        XmSINGLE_SELECT ); n++;
1010   XtSetArg( args[ n ], XmNlistMarginHeight,       5 ); n++;
1011   XtSetArg( args[ n ], XmNlistMarginWidth,        5 ); n++;
1012   groupLi = XmCreateScrolledList( workFo, "GroupLi", args, n );
1013 
1014   XtAddCallback( groupLi, XmNdefaultActionCallback,
1015                  (XtCallbackProc) addFromListCB, (XtPointer) send_ref );
1016 
1017 
1018   /* Calendar/Mail address. */
1019   toFieldRc = XmCreateRowColumn( workFo, "ToFieldRc", args, 0 );
1020 
1021   toFieldLa = xitCreateLabel( toFieldRc, "ToFieldLa",
1022                               msgGetText( MXDI_MSG_CAL_MAIL_ADDR_LABEL ), -1 );
1023   toFieldTx = xitCreateTextCols( toFieldRc, &text_buffer_def[ 0 ], 25 );
1024 
1025   XtAddCallback( toFieldTx, XmNactivateCallback,
1026                  (XtCallbackProc) doAddRecipientsCB, (XtPointer) send_ref );
1027 
1028   n = 0;
1029   XtSetArg( args[ n ], XmNmaxLength, 50 ); n++;
1030   XtSetValues( toFieldTx, args, n );
1031 
1032 
1033   /* Add recipients. */
1034   n = 0;
1035   XtSetArg( args[ n ], XmNorientation,  XmHORIZONTAL ); n++;
1036   XtSetArg( args[ n ], XmNspacing,      10 ); n++;
1037   XtSetArg( args[ n ], XmNmarginHeight, 10 ); n++;
1038   srcActionRc = XmCreateRowColumn( workFo, "SrcActionRc", args, n );
1039 
1040   for( index = 0; index < XtNumber( source_action_def ); index++ )
1041     srcActionBu[ index ] = xitCreatePushButton(
1042                              srcActionRc, &source_action_def[ index ] );
1043 
1044   XtAddCallback( srcActionBu[ 0 ], XmNactivateCallback,
1045                  (XtCallbackProc) doAddRecipientsCB, (XtPointer) send_ref );
1046 
1047 
1048   /* Separator. */
1049   n = 0;
1050   XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL );  n++;
1051   ho1Sp = XmCreateSeparatorGadget( workFo, "Ho1Sp", args, n );
1052 
1053 
1054   /* 'What to do next' help text. */
1055   nextInfoLa = xitCreateLabel( workFo, "NextInfoLa",
1056                                msgGetText( MXDI_MSG_NEXT_INFO_LABEL ), -1 );
1057 
1058 
1059   /* Place the main elements together. */
1060   xitAttachWidget( menuBr,
1061                    XmATTACH_FORM, NULL, XmATTACH_FORM, NULL,
1062                    XmATTACH_FORM, NULL, XmATTACH_NONE, NULL );
1063   xitAttachWidget( genInfoLa,
1064                    XmATTACH_WIDGET, menuBr, XmATTACH_FORM, NULL,
1065                    XmATTACH_NONE,   NULL,   XmATTACH_NONE, NULL );
1066   xitAttachWidget( toLa,
1067                    XmATTACH_WIDGET, genInfoLa, XmATTACH_FORM, NULL,
1068                    XmATTACH_NONE,   NULL,      XmATTACH_NONE, NULL );
1069   xitAttachWidget( XtParent( toLi ),
1070                    XmATTACH_WIDGET, toLa, XmATTACH_FORM,   NULL,
1071                    XmATTACH_NONE,   NULL, XmATTACH_WIDGET, toActionRc );
1072   xitAttachWidget( toActionRc,
1073                    XmATTACH_NONE, NULL, XmATTACH_FORM, NULL,
1074                    XmATTACH_NONE, NULL,
1075                    XmATTACH_OPPOSITE_WIDGET, srcActionRc );
1076   xitAttachWidget( dbLa,
1077                    XmATTACH_WIDGET, genInfoLa, XmATTACH_FORM, NULL,
1078                    XmATTACH_NONE,   NULL,      XmATTACH_NONE, NULL );
1079   xitAttachWidget( XtParent( dbLi ),
1080                    XmATTACH_WIDGET, dbLa,
1081                    XmATTACH_OPPOSITE_WIDGET, dbLa,
1082                    XmATTACH_FORM, NULL, XmATTACH_NONE, NULL );
1083   xitAttachWidget( groupLa,
1084                    XmATTACH_WIDGET, XtParent( dbLi ),
1085                    XmATTACH_OPPOSITE_WIDGET, dbLa,
1086                    XmATTACH_NONE, NULL, XmATTACH_NONE, NULL );
1087   xitAttachWidget( XtParent( groupLi ),
1088                    XmATTACH_WIDGET, groupLa,
1089                    XmATTACH_OPPOSITE_WIDGET, dbLa,
1090                    XmATTACH_FORM, NULL, XmATTACH_NONE, NULL );
1091   xitAttachWidget( toFieldRc,
1092                    XmATTACH_WIDGET, XtParent( groupLi ),
1093                    XmATTACH_OPPOSITE_WIDGET, dbLa,
1094                    XmATTACH_NONE, NULL, XmATTACH_NONE, NULL );
1095   xitAttachWidget( srcActionRc,
1096                    XmATTACH_WIDGET, toFieldRc,
1097                    XmATTACH_OPPOSITE_WIDGET, dbLa,
1098                    XmATTACH_NONE, NULL, XmATTACH_NONE, NULL );
1099   xitAttachWidget( ho1Sp,
1100                    XmATTACH_WIDGET, srcActionRc, XmATTACH_FORM, NULL,
1101                    XmATTACH_FORM,   NULL,        XmATTACH_NONE, NULL );
1102   xitAttachWidget( nextInfoLa,
1103                    XmATTACH_WIDGET, ho1Sp, XmATTACH_FORM, NULL,
1104                    XmATTACH_NONE,   NULL,  XmATTACH_NONE, NULL );
1105 
1106   /* Make sure there is enough space between the children. */
1107   n = 0;
1108   XtSetArg( args[ n ], XmNtopOffset,    5 ); n++;
1109   XtSetArg( args[ n ], XmNleftOffset,   5 ); n++;
1110   XtSetArg( args[ n ], XmNrightOffset,  5 ); n++;
1111   XtSetArg( args[ n ], XmNbottomOffset, 5 ); n++;
1112   XtSetValues( genInfoLa,           args, n );
1113   XtSetValues( toLa,                args, n );
1114   XtSetValues( XtParent( toLi ),    args, n );
1115   XtSetValues( toActionRc,          args, n );
1116   XtSetValues( dbLa,                args, n );
1117   XtSetValues( XtParent( dbLi ),    args, n );
1118   XtSetValues( groupLa,             args, n );
1119   XtSetValues( XtParent( groupLi ), args, n );
1120   XtSetValues( toFieldRc,           args, n );
1121   XtSetValues( srcActionRc,         args, n );
1122   XtSetValues( nextInfoLa,          args, n );
1123 
1124   n = 0;
1125   XtSetArg( args[ n ], XmNtopOffset,    5 ); n++;
1126   XtSetArg( args[ n ], XmNbottomOffset, 5 ); n++;
1127   XtSetValues( ho1Sp, args, n );
1128 
1129   n = 0;
1130   XtSetArg( args[ n ], XmNbottomOffset, 0 ); n++;
1131   XtSetValues( toActionRc,  args, n );
1132   XtSetValues( srcActionRc, args, n );
1133 
1134 
1135   /* Manage all the children. */
1136   XtManageChildren( menuCasc,    XtNumber( menuCasc ) );
1137   XtManageChildren( menuHelpBu,  XtNumber( menuHelpBu ) );
1138   XtManageChildren( menuFileBu,  XtNumber( menuFileBu ) );
1139   XtManageChildren( toActionBu,  XtNumber( toActionBu ) );
1140   XtManageChildren( srcActionBu, XtNumber( srcActionBu ) );
1141 
1142   xitManageChildren( dataLocalW, XtNumber( dataLocalW ) );
1143 
1144 
1145   /* Set icon for this window. */
1146   xtmIcSetSimpleIcon( msgSendTl, workFo, XTM_IC_ICON_MAIL );
1147 
1148   /* Set the size of the window. */
1149   xitSetSizeToplevelDialog( msgSendTl, True );
1150 
1151 
1152   /* Make sure our children don't spoil our size. */
1153   n = 0;
1154   XtSetArg( args[ n ], XmNallowShellResize, False ); n++;
1155   XtSetValues( msgSendTl, args, n );
1156 
1157   /* Make the final attachments. */
1158   n = 0;
1159   XtSetArg( args[ n ], XmNrightAttachment, XmATTACH_POSITION ); n++;
1160   XtSetArg( args[ n ], XmNrightPosition,   50 ); n++;
1161   XtSetValues( XtParent( toLi ), args, n );
1162 
1163   n = 0;
1164   XtSetArg( args[ n ], XmNleftAttachment, XmATTACH_POSITION ); n++;
1165   XtSetArg( args[ n ], XmNleftPosition,   50 ); n++;
1166   XtSetValues( dbLa, args, n );
1167 
1168 
1169 
1170   return( msgSendTl );
1171 
1172 } /* createRecipientWindow */
1173 
1174 
1175 /*----------------------------------------------------------------------*/
1176 
1177 static void
setRecipientWindowValues(SEND_REC_REF send_ref)1178   setRecipientWindowValues( SEND_REC_REF  send_ref )
1179 {
1180 
1181   /* Variables. */
1182   int                     index;
1183   int                     index1;
1184   char                    buffer[ 100 ];
1185   char                    *char_ref;
1186   char                    *db_names;
1187   Arg                     args[ 5 ];
1188   Cardinal                n;
1189   Widget                  mainW;
1190   Widget                  tempW;
1191   XmString                list_items[ 100 ];
1192   XTM_GL_BASE_DATA_REF    appl_data_ref;
1193   XTM_GL_CUSTOM_DATA_REF  custom_data_ref;
1194 
1195 
1196   /* Code. */
1197 
1198   appl_data_ref   = send_ref -> appl_data_ref;
1199   custom_data_ref = appl_data_ref -> custom_data;
1200 
1201   mainW = XtNameToWidget( send_ref -> recipientW,
1202                           "MsgSendTlBase.MsgSendTlFo" );
1203 
1204   /* Set the to list. */
1205   tempW = XtNameToWidget( mainW, "ToLiSW.ToLi" );
1206 
1207   n = 0;
1208   XtSetArg( args[ n ], XmNitems, NULL ); n++;
1209   XtSetArg( args[ n ], XmNitemCount, 0 ); n++;
1210   XtSetValues( tempW, args, n );
1211 
1212 
1213   /* Set the calendars. */
1214   (void) xtmCdFetchDbNames( custom_data_ref -> cal_db_handle, &db_names );
1215   char_ref = db_names;
1216   index    = 0;
1217 
1218   do {
1219 
1220     int              char_read;
1221     char             db_name[ XTM_GL_MAX_CAL_NAME + 1 ];
1222     XTM_CD_CAL_INFO  db_info;
1223 
1224     while( isspace( *char_ref ) )
1225       char_ref++;
1226 
1227     if( *char_ref == '\0' )
1228       break;
1229 
1230     char_read = strlen( char_ref );
1231     sscanf( char_ref, "%s%n", db_name, &char_read );
1232     char_ref = char_ref + char_read;
1233 
1234 
1235     /* Fetch information about the database. */
1236     (void) xtmCdFetchNamedDb( custom_data_ref -> cal_db_handle, db_name,
1237                               &db_info, NULL );
1238 
1239     sprintf( buffer, "%-15.15s", db_info.short_name );
1240 
1241     list_items[ index ] = XmStringCreate( buffer, CS );
1242     index++;
1243 
1244   } while( True );
1245 
1246   if( db_names != NULL )
1247     SysFree( db_names );
1248 
1249 
1250   /* The list is always sorted. */
1251   xitSortStringList( list_items, index );
1252 
1253   tempW = XtNameToWidget( mainW, "DbLiSW.DbLi" );
1254 
1255   n = 0;
1256   XtSetArg( args[ n ], XmNitems, list_items ); n++;
1257   XtSetArg( args[ n ], XmNitemCount, index ); n++;
1258   XtSetValues( tempW, args, n );
1259 
1260   /* Free allocated memory. */
1261   for( index1 = 0; index1 < index; index1++ )
1262     XmStringFree( list_items[ index1 ] );
1263 
1264 
1265 
1266   /* Set values for the groups. */
1267   index = 0;
1268 
1269   {
1270     int   char_read;
1271     char  group_name[ XTM_GD_MAX_GROUP_NAME + 1 ];
1272     char  *group_name_ref;
1273     char  *group_names;
1274 
1275     (void) xtmGdFetchGroupNames( custom_data_ref -> group_db_handle,
1276                                  &group_names );
1277 
1278     group_name_ref = group_names;
1279 
1280     do {
1281 
1282       while( isspace( *group_name_ref ) )
1283         group_name_ref++;
1284 
1285       if( *group_name_ref == '\0' )
1286         break;
1287 
1288       char_read = strlen( group_name_ref );
1289       sscanf( group_name_ref, "%s%n", group_name, &char_read );
1290       group_name_ref = group_name_ref + char_read;
1291 
1292       sprintf( buffer, "%s", group_name );
1293 
1294       list_items[ index ] = XmStringCreate( buffer, CS );
1295       index++;
1296 
1297     } while( True );
1298 
1299     SysFree( group_names );
1300 
1301   } /* block */
1302 
1303 
1304   /* The list is always sorted. */
1305   xitSortStringList( list_items, index );
1306 
1307   tempW = XtNameToWidget( mainW, "GroupLiSW.GroupLi" );
1308 
1309   n = 0;
1310   XtSetArg( args[ n ], XmNitems, list_items ); n++;
1311   XtSetArg( args[ n ], XmNitemCount, index ); n++;
1312   XtSetValues( tempW, args, n );
1313 
1314   /* Free allocated memory. */
1315   for( index1 = 0; index1 < index; index1++ )
1316     XmStringFree( list_items[ index1 ] );
1317 
1318   send_ref -> to_list_entry = -1;
1319 
1320 
1321   return;
1322 
1323 } /* setRecipientWindowValues */
1324 
1325 
1326 /*----------------------------------------------------------------------*/
1327 
1328 static void
setMessageWindowValues(SEND_REC_REF send_ref,char * db_name,UINT32 id)1329   setMessageWindowValues( SEND_REC_REF  send_ref,
1330                           char          *db_name,
1331                           UINT32        id )
1332 {
1333 
1334   /* Variables. */
1335   Boolean                 ok;
1336   char                    buffer[ 100 ];
1337   Widget                  baseW;
1338   Widget                  mainW;
1339   Widget                  tempW;
1340   TIM_TIME_REF            default_time;
1341   XTM_DB_ALL_ENTRY_DEF    entry_record;
1342   XTM_DB_ENTRY_DATABASES  database;
1343   XTM_DB_STATUS           db_status;
1344   XTM_GL_BASE_DATA_REF    appl_data_ref;
1345   XTM_GL_CUSTOM_DATA_REF  custom_data_ref;
1346 
1347 
1348   /* Code. */
1349 
1350   appl_data_ref   = send_ref -> appl_data_ref;
1351   custom_data_ref = appl_data_ref -> custom_data;
1352 
1353   mainW = XtNameToWidget( send_ref -> messageW, "MsgFdFo" );
1354 
1355   /* Set default appointment data? */
1356   if( id == 0 ) {
1357 
1358     baseW = XtNameToWidget( mainW, "TimeEntFr.TimeEntRc" );
1359 
1360     /* Appointment date. */
1361     tempW = XtNameToWidget( baseW, "DateEntTb" );
1362 
1363     if( send_ref -> default_entry_date == (TIM_TIME_REF) 0 )
1364       XmUbTimeBoxSetStartDate( tempW, TimLocalTime( TimMakeTimeNow() ) );
1365     else
1366       XmUbTimeBoxSetStartDate( tempW, send_ref -> default_entry_date );
1367 
1368 
1369     /* Appointment time. */
1370     default_time = TimMakeTime( 1970, 1, 1, 12, 0, 0 );
1371 
1372     tempW = XtNameToWidget( baseW, "StartEntTb" );
1373     XmUbTimeBoxSetStartTime( tempW, default_time );
1374 
1375 
1376     /* Duration. */
1377     sprintf( buffer, "%d:%02d",
1378              custom_data_ref -> default_entry_delta / 60,
1379              custom_data_ref -> default_entry_delta % 60 );
1380 
1381     tempW = XtNameToWidget( baseW, "DurEntFs" );
1382     xitFieldSelectSetCurrent( tempW, buffer, False );
1383 
1384     return;
1385 
1386   } /* if */
1387 
1388 
1389   /* Open the database and fetch the entry. */
1390   ok = xtmDmOpenDatabase( appl_data_ref, db_name, XTM_DB_FLAG_MODE_READ,
1391                           &database );
1392   if( ! ok )
1393     return;
1394 
1395 
1396   /* Fetch the entry. */
1397   db_status = xtmDbFetchEntry( &database, id,
1398                                &entry_record, &entry_record.all_text );
1399 
1400   xtmDbCloseEntryDb( &database );
1401 
1402 
1403   if( db_status != XTM_DB_OK ) {
1404     xitErMessage( send_ref -> recipientW, XIT_ER_ERROR,
1405                   module_name, "setSendWindowValues",
1406                   msgGetText( MXDI_NO_ENTRY ) );
1407 
1408     return;
1409   }
1410 
1411 
1412   baseW = XtNameToWidget( mainW, "TimeEntFr.TimeEntRc" );
1413 
1414 
1415   /* Date for the appointment. */
1416   tempW = XtNameToWidget( baseW, "DateEntTb" );
1417 
1418   if( entry_record.entry.entry_type == XTM_DB_DAY_ENTRY )
1419     XmUbTimeBoxSetStartDate( tempW, entry_record.entry.date_stamp );
1420   else
1421     XmUbTimeBoxSetStartDateString( tempW, "" );
1422 
1423 
1424   /* Time for the appointment. */
1425   tempW = XtNameToWidget( baseW, "StartEntTb" );
1426 
1427   if( entry_record.entry.entry_type == XTM_DB_DAY_ENTRY )
1428     XmUbTimeBoxSetStartTime( tempW, entry_record.entry.time_stamp );
1429   else
1430     XmUbTimeBoxSetStartTimeString( tempW, "" );
1431 
1432 
1433   /* Duration of the appointment. */
1434   /* sprintf( buffer, "" ); */
1435 
1436   switch( entry_record.entry.entry_type ) {
1437     case XTM_DB_DAY_ENTRY:
1438       if( entry_record.entry.duration > 0 )
1439         sprintf( buffer, "%2d:%02d",
1440                  (int) entry_record.entry.duration / 60,
1441                  (int) entry_record.entry.duration % 60 );
1442       break;
1443   } /* switch */
1444 
1445   tempW = XtNameToWidget( baseW, "DurEntFs" );
1446   xitFieldSelectSetCurrent( tempW, buffer, False );
1447 
1448 
1449   /* Appointment text. */
1450   tempW = XtNameToWidget( mainW, "TextTxSW.TextTx" );
1451 
1452   if( entry_record.all_text != NULL )
1453     XmTextSetString( tempW, entry_record.all_text );
1454   else
1455     XmTextSetString( tempW, entry_record.entry.text );
1456 
1457 
1458   if( entry_record.all_text != NULL )
1459     SysFree( entry_record.all_text );
1460 
1461 
1462   return;
1463 
1464 } /* setMessageWindowValues */
1465 
1466 
1467 /*----------------------------------------------------------------------*/
1468 
1469 static void
addFromListCB(Widget widget,SEND_REC_REF send_ref,XmListCallbackStruct * call_data)1470   addFromListCB( Widget                widget,
1471                  SEND_REC_REF          send_ref,
1472                  XmListCallbackStruct  *call_data )
1473 {
1474 
1475   /* Code. */
1476 
1477   /* This is called from a list default selection, select the object! */
1478   XmListSelectPos( widget, call_data -> item_position, False );
1479 
1480   doAddRecipientsCB( widget, send_ref, NULL );
1481 
1482 
1483   return;
1484 
1485 } /* addFromListCB */
1486 
1487 
1488 /*----------------------------------------------------------------------*/
1489 
1490 static void
clearToCB(Widget widget,SEND_REC_REF send_ref,XtPointer call_data)1491   clearToCB( Widget        widget,
1492              SEND_REC_REF  send_ref,
1493              XtPointer     call_data )
1494 {
1495 
1496   /* Variables. */
1497   Arg       args[ 5 ];
1498   Cardinal  n;
1499   Widget    mainW;
1500   Widget    tempW;
1501 
1502 
1503   /* Code. */
1504 
1505   mainW = XtNameToWidget( send_ref -> recipientW,
1506                           "MsgSendTlBase.MsgSendTlFo" );
1507 
1508   /* Remove all items in the to list. */
1509   tempW = XtNameToWidget( mainW, "ToLiSW.ToLi" );
1510 
1511   n = 0;
1512   XtSetArg( args[ n ], XmNitems, NULL ); n++;
1513   XtSetArg( args[ n ], XmNitemCount, 0 ); n++;
1514   XtSetValues( tempW, args, n );
1515 
1516 
1517   return;
1518 
1519 } /* clearCB */
1520 
1521 
1522 /*----------------------------------------------------------------------*/
1523 
1524 static void
closeCB(Widget widget,SEND_REC_REF send_ref,XtPointer call_data)1525   closeCB( Widget        widget,
1526            SEND_REC_REF  send_ref,
1527            XtPointer     call_data )
1528 {
1529 
1530   /* Code. */
1531 
1532   /* We don't need the message window anymore. */
1533   if( send_ref -> messageW != NULL )
1534     msgCloseCB( send_ref -> messageW, send_ref, NULL );
1535 
1536 
1537   XtPopdown( send_ref -> recipientW );
1538 
1539 
1540   return;
1541 
1542 } /* closeCB */
1543 
1544 
1545 /*----------------------------------------------------------------------*/
1546 
1547 static void
deleteToCB(Widget widget,SEND_REC_REF send_ref,XtPointer call_data)1548   deleteToCB( Widget        widget,
1549               SEND_REC_REF  send_ref,
1550               XtPointer     call_data )
1551 {
1552 
1553   /* Variables. */
1554   Widget    mainW;
1555   Widget    tempW;
1556 
1557 
1558   /* Code. */
1559 
1560   mainW = XtNameToWidget( send_ref -> recipientW,
1561                           "MsgSendTlBase.MsgSendTlFo" );
1562 
1563   /* Any selection in the to list? */
1564   if( send_ref -> to_list_entry < 0 )
1565     return;
1566 
1567   /* Delete the entry. */
1568   tempW = XtNameToWidget( mainW, "ToLiSW.ToLi" );
1569   XmListDeletePos( tempW, send_ref -> to_list_entry );
1570 
1571   XmListDeselectAllItems( tempW );
1572 
1573   send_ref -> to_list_entry = -1;
1574 
1575 
1576   return;
1577 
1578 } /* deleteToCB */
1579 
1580 
1581 /*----------------------------------------------------------------------*/
1582 
1583 static void
destroyCB(Widget widget,SEND_REC_REF send_ref,XtPointer call_data)1584   destroyCB( Widget        widget,
1585              SEND_REC_REF  send_ref,
1586              XtPointer     call_data )
1587 {
1588 
1589   /* Code. */
1590 
1591   /* File selection. */
1592   if( send_ref -> fileSelectW != NULL )
1593     XtDestroyWidget( send_ref -> fileSelectW );
1594 
1595   /* Release the user data. */
1596   SysFree( send_ref );
1597 
1598 
1599   return;
1600 
1601 } /* destroyCB */
1602 
1603 
1604 /*----------------------------------------------------------------------*/
1605 
1606 static void
doAddRecipientsCB(Widget widget,SEND_REC_REF send_ref,XtPointer call_data)1607   doAddRecipientsCB( Widget        widget,
1608                      SEND_REC_REF  send_ref,
1609                      XtPointer     call_data )
1610 {
1611 
1612   /* Variables. */
1613   Boolean                 ok;
1614   int                     items;
1615   int                     selected_item_count;
1616   char                    to_user[ 100 ];
1617   char                    buffer[ 51 ];
1618   char                    location[ 51 ];
1619   char                    *char_ref;
1620   Arg                     args[ 5 ];
1621   Cardinal                n;
1622   Widget                  mainW;
1623   Widget                  tempW;
1624   XmString                *selected_items;
1625   XmString                xstr;
1626   XTM_GL_CUSTOM_DATA_REF  custom_data_ref;
1627   XTM_CD_CAL_INFO         db_info;
1628 
1629 
1630   /* Code. */
1631 
1632   custom_data_ref = send_ref -> appl_data_ref -> custom_data;
1633   mainW           = XtNameToWidget( send_ref -> recipientW,
1634                                     "MsgSendTlBase.MsgSendTlFo" );
1635 
1636   /* Any database selection? */
1637   tempW = XtNameToWidget( mainW, "DbLiSW.DbLi" );
1638 
1639   n = 0;
1640   XtSetArg( args[ n ], XmNselectedItemCount, &selected_item_count ); n++;
1641   XtSetArg( args[ n ], XmNselectedItems, &selected_items ); n++;
1642   XtGetValues( tempW, args, n );
1643 
1644   if( selected_item_count == 1 ) {
1645     tempW = XtNameToWidget( mainW, "ToLiSW.ToLi" );
1646 
1647     XmListAddItemUnselected( tempW, *selected_items, 0 );
1648 
1649     tempW = XtNameToWidget( mainW, "DbLiSW.DbLi" );
1650     XmListDeselectAllItems( tempW );
1651   }
1652 
1653 
1654   /* Any group selection? */
1655   tempW = XtNameToWidget( mainW, "GroupLiSW.GroupLi" );
1656 
1657   n = 0;
1658   XtSetArg( args[ n ], XmNselectedItemCount, &selected_item_count ); n++;
1659   XtSetArg( args[ n ], XmNselectedItems, &selected_items ); n++;
1660   XtGetValues( tempW, args, n );
1661 
1662   if( selected_item_count == 1 ) {
1663     tempW = XtNameToWidget( mainW, "ToLiSW.ToLi" );
1664 
1665     XmListAddItemUnselected( tempW, *selected_items, 0 );
1666 
1667     tempW = XtNameToWidget( mainW, "GroupLiSW.GroupLi" );
1668     XmListDeselectAllItems( tempW );
1669   }
1670 
1671 
1672   /* To mail address. */
1673   tempW    = XtNameToWidget( mainW, "ToFieldRc.ToFieldTx" );
1674   char_ref = xitStringGetText( tempW );
1675 
1676   items = sscanf( char_ref, "%s", to_user );
1677   SysFree( char_ref );
1678 
1679   if( items == 1 ) {
1680 
1681     XmTextSetString( tempW, "" );
1682 
1683     sprintf( buffer, "%s", to_user );
1684 
1685     /* Check if a 'real' calendar. */
1686     ok = xtmCdFetchNamedDb( custom_data_ref -> cal_db_handle, to_user,
1687                             &db_info, NULL );
1688 
1689     /* Try to locate the calendar? */
1690     if( ! ok ) {
1691       ok = xtmLcLocateCalendar( send_ref -> recipientW, to_user,
1692                                 custom_data_ref -> find_location_script,
1693                                 location, sizeof( location ) );
1694 
1695       if( ok && strlen( location ) > 0 )
1696         sprintf( buffer, "%-15.15s (%s)", to_user, location );
1697       else
1698         sprintf( buffer, "%.40s (%s)",
1699                  to_user, msgGetText( MXDI_SEND_AS_MAIL ) );
1700     }
1701 
1702     tempW = XtNameToWidget( mainW, "ToLiSW.ToLi" );
1703 
1704     xstr = XmStringCreateLtoR( buffer, CS );
1705     XmListAddItemUnselected( tempW, xstr, 0 );
1706     XmStringFree( xstr );
1707 
1708   } /* if */
1709 
1710 
1711   /* No selections in the To list. */
1712   tempW = XtNameToWidget( mainW, "ToLiSW.ToLi" );
1713 
1714   XmListDeselectAllItems( tempW );
1715   XmListSetBottomPos( tempW, 0 );
1716 
1717   send_ref -> to_list_entry = -1;
1718 
1719 
1720   return;
1721 
1722 } /* doAddRecipientsCB */
1723 
1724 
1725 /*----------------------------------------------------------------------*/
1726 
1727 static void
includeFileCB(Widget widget,SEND_REC_REF send_ref,XtPointer call_data)1728   includeFileCB( Widget        widget,
1729                  SEND_REC_REF  send_ref,
1730                  XtPointer     call_data )
1731 {
1732 
1733   /* Variables. */
1734   XIT_FILE_SEL_LABELS  labels;
1735 
1736 
1737   /* Code. */
1738 
1739   /* Do we need to create the dialog? */
1740   if( send_ref -> fileSelectW == NULL ) {
1741 
1742     labels.dir_list_label       = msgGetText( MXDI_DIRECTORY_LABEL );
1743     labels.file_list_label      = msgGetText( MXDI_FILES_LABEL );
1744     labels.filter_label         = msgGetText( MXDI_FILTER_ACTION_LABEL );
1745     labels.selection_label      = msgGetText( MXDI_SELECTION_LABEL );
1746     labels.cancel_button        = msgGetText( MXDI_CANCEL_BUTTON );
1747     labels.filter_button        = msgGetText( MXDI_FILTER_ACTION_LABEL );
1748     labels.ok_button            = msgGetText( MXDI_OK_BUTTON );
1749     labels.no_file_sel_msg      = msgGetText( MXDI_NO_FILE_SELECTED );
1750     labels.cannot_read_file_msg = msgGetText( MXDI_CANNOT_READ_FILE );
1751 
1752     /* The file selection dialog. */
1753     send_ref -> fileSelectW =
1754       xitCreateFileSelect( send_ref -> messageW, "FileSelect",
1755                            0,
1756                            "", &labels,
1757                            includeFileActionCB, (void *) send_ref );
1758 
1759   } /* if */
1760 
1761   /* Display the dialog. */
1762   xitFileSelectDisplay( send_ref -> fileSelectW );
1763 
1764 
1765   return;
1766 
1767 } /* includeFileCB */
1768 
1769 
1770 /*----------------------------------------------------------------------*/
1771 
1772 static void
includeFileActionCB(XIT_FILE_SEL_REASON reason,char * file_name,void * user_data)1773   includeFileActionCB( XIT_FILE_SEL_REASON  reason,
1774                        char                 *file_name,
1775                        void                 *user_data )
1776 {
1777 
1778   /* Variables. */
1779   Widget        mainW;
1780   Widget        tempW;
1781   SEND_REC_REF  send_ref;
1782 
1783 
1784   /* Code. */
1785 
1786   send_ref = (SEND_REC_REF) user_data;
1787 
1788   mainW = XtNameToWidget( send_ref -> messageW, "MsgFdFo" );
1789 
1790   /* Only OK reasons. */
1791   if( reason != XIT_FILE_SELECT_OK )
1792     return;
1793 
1794   tempW = XtNameToWidget( mainW, "TextTxSW.TextTx" );
1795   xitStringSetTextFromFile( tempW, file_name );
1796 
1797 
1798   return;
1799 
1800 } /* includeFileActionCB */
1801 
1802 
1803 /*----------------------------------------------------------------------*/
1804 
1805 static void
infoCB(Widget widget,SEND_REC_REF send_ref,XmRowColumnCallbackStruct * call_data)1806   infoCB( Widget                     widget,
1807           SEND_REC_REF               send_ref,
1808           XmRowColumnCallbackStruct  *call_data )
1809 {
1810 
1811   /* Code. */
1812 
1813   xtmHlDisplayHelp( send_ref -> appl_data_ref -> info_handle,
1814                     (intptr_t) call_data -> data,
1815                     send_window_id, "" );
1816 
1817   return;
1818 
1819 } /* infoCB */
1820 
1821 
1822 /*----------------------------------------------------------------------*/
1823 
1824 static void
messageCB(Widget widget,SEND_REC_REF send_ref,XtPointer call_data)1825   messageCB( Widget        widget,
1826              SEND_REC_REF  send_ref,
1827              XtPointer     call_data )
1828 {
1829 
1830   /* Variables. */
1831   Widget  tempW;
1832 
1833 
1834   /* Code. */
1835 
1836   /* Is the message window created? */
1837   if( send_ref -> messageW == NULL )
1838     send_ref -> messageW = createMessageWindow( send_ref -> recipientW,
1839                                                 send_ref );
1840 
1841   /* Add entry to the window. */
1842   if( ! send_ref -> entry_added ) {
1843     setMessageWindowValues( send_ref,
1844                             send_ref -> db_name, send_ref -> entry_id );
1845 
1846     send_ref -> entry_added = True;
1847   }
1848 
1849   XtManageChild( send_ref -> messageW );
1850 
1851 
1852   /* Start at the text field. */
1853   tempW = XtNameToWidget( send_ref -> messageW, "MsgFdFo.TextTxSW.TextTx" );
1854   xitGrabFocus( tempW );
1855 
1856 
1857   return;
1858 
1859 } /* messageCB */
1860 
1861 
1862 /*----------------------------------------------------------------------*/
1863 
1864 static void
msgCloseCB(Widget widget,SEND_REC_REF send_ref,XtPointer call_data)1865   msgCloseCB( Widget        widget,
1866               SEND_REC_REF  send_ref,
1867               XtPointer     call_data )
1868 {
1869 
1870   /* Code. */
1871 
1872   XtUnmanageChild( send_ref -> messageW );
1873 
1874 
1875   return;
1876 
1877 } /* msgCloseCB */
1878 
1879 
1880 /*----------------------------------------------------------------------*/
1881 
1882 static void
sendCB(Widget widget,SEND_REC_REF send_ref,XtPointer call_data)1883   sendCB( Widget        widget,
1884           SEND_REC_REF  send_ref,
1885           XtPointer     call_data )
1886 {
1887 
1888   /* Variables. */
1889   Boolean                 mail_fail;
1890   Boolean                 ok;
1891   Boolean                 only_mail;
1892   int                     duration = 0;
1893   int                     msg_to_count;
1894   char                    *char_ref;
1895   char                    *message;
1896   char                    *text;
1897   Arg                     args[ 5 ];
1898   Cardinal                n;
1899   Widget                  baseW;
1900   Widget                  mainW;
1901   Widget                  tempW;
1902   XmStringTable           msg_to;
1903   TIM_TIME_REF            entry_date;
1904   TIM_TIME_REF            entry_time;
1905   XTM_GL_BASE_DATA_REF    appl_data_ref;
1906   XTM_GL_CUSTOM_DATA_REF  custom_data_ref;
1907 
1908 
1909   /* Code. */
1910 
1911   appl_data_ref   = send_ref -> appl_data_ref;
1912   custom_data_ref = appl_data_ref -> custom_data;
1913 
1914 
1915   /* Values from the recipients window. */
1916   mainW = XtNameToWidget( send_ref -> recipientW,
1917                           "MsgSendTlBase.MsgSendTlFo" );
1918 
1919   /* Addresses to selected. */
1920   tempW = XtNameToWidget( mainW, "ToLiSW.ToLi" );
1921 
1922   n = 0;
1923   XtSetArg( args[ n ], XmNitemCount, &msg_to_count ); n++;
1924   XtSetArg( args[ n ], XmNitems, &msg_to ); n++;
1925   XtGetValues( tempW, args, n );
1926 
1927 
1928   /* Anyone to send to? */
1929   if( msg_to_count < 1 ) {
1930     xitErMessage( send_ref -> recipientW, XIT_ER_ERROR,
1931                   module_name, "sendCB",
1932                   msgGetText( MXDI_NO_RECIPIENTS ) );
1933     return;
1934   }
1935 
1936 
1937   /* Values from the message window. */
1938   mainW = XtNameToWidget( send_ref -> messageW, "MsgFdFo" );
1939 
1940   baseW = XtNameToWidget( mainW, "TimeEntFr.TimeEntRc" );
1941 
1942 
1943   /* Fetch the appointment date. */
1944   tempW = XtNameToWidget( baseW, "DateEntTb" );
1945 
1946   ok = xtmFoFetchDate( mainW, tempW, XTM_FO_START_DATE, True, &entry_date );
1947   if( ! ok )
1948     return;
1949 
1950 
1951   /* Fetch the start time. */
1952   tempW = XtNameToWidget( baseW, "StartEntTb" );
1953 
1954   ok = xtmFoFetchTime( mainW, tempW, XTM_FO_START_TIME, True, &entry_time );
1955   if( ! ok )
1956     return;
1957 
1958 
1959   /* Fetch the duration. */
1960   tempW = XtNameToWidget( baseW, "DurEntFs" );
1961   xitFieldSelectGetCurrent( tempW, &char_ref );
1962 
1963   ok = xtmFoFetchMinuteTime( char_ref, True,
1964                              send_ref -> recipientW, 12 * 60,
1965                              &duration );
1966   SysFree( char_ref );
1967   if( ! ok )
1968     return;
1969 
1970   if( duration < 0 )
1971     duration = 0;
1972 
1973 
1974   /* Flags. */
1975   tempW = XtNameToWidget( mainW, "FlagsRc.OnlyMailTb" );
1976   only_mail = XmToggleButtonGetState( tempW );
1977 
1978   tempW = XtNameToWidget( mainW, "FlagsRc.MailFailTb" );
1979   mail_fail = XmToggleButtonGetState( tempW );
1980 
1981 
1982   /* Appointment message. */
1983   tempW = XtNameToWidget( mainW, "MsgTxSW.MsgTx" );
1984   message = xitStringGetText( tempW );
1985 
1986 
1987   /* Appointment text. */
1988   tempW = XtNameToWidget( mainW, "TextTxSW.TextTx" );
1989   text  = xitStringGetText( tempW );
1990 
1991 
1992   /* Send the message (as mail or XDiary message). */
1993   ok = xtmMbSendMessage( appl_data_ref, send_ref -> messageW,
1994                          msg_to_count, msg_to,
1995                          only_mail, mail_fail,
1996                          entry_date, entry_time, duration,
1997                          message, text );
1998 
1999   /* Free occupied memory. */
2000   SysFree( message );
2001   SysFree( text );
2002 
2003 
2004   /* Close the window. */
2005   msgCloseCB( widget, send_ref, call_data );
2006 
2007 
2008   /* Tell we are done. */
2009   (void) xitCreateInformationDialog(
2010            send_ref -> recipientW, "InformationDialog",
2011            msgGetText( MXDI_INFO_MESSAGE_LABEL ),
2012            msgGetText( MXDI_MESSAGE_SENT ),
2013            NULL, NULL );
2014 
2015 
2016   return;
2017 
2018 } /* sendCB */
2019 
2020 
2021 /*----------------------------------------------------------------------*/
2022 
2023 static void
toListCB(Widget widget,SEND_REC_REF send_ref,XmListCallbackStruct * call_data)2024   toListCB( Widget                widget,
2025             SEND_REC_REF          send_ref,
2026             XmListCallbackStruct  *call_data )
2027 {
2028 
2029   /* Code. */
2030 
2031   send_ref -> to_list_entry = call_data -> item_position;
2032 
2033 
2034   return;
2035 
2036 } /* toListCB */
2037