1 /*----------------------------------------------------------------------------
2 --
3 --  Module:           xtmMsgSelect
4 --
5 --  Project:          Xdiary
6 --  System:           xtm - X Desktop Calendar
7 --    Subsystem:      <>
8 --    Function block: <>
9 --
10 --  Description:
11 --    Select message(s) to read and answer.
12 --
13 --  Filename:         xtmMsgSelect.c
14 --
15 --  Authors:          Roger Larsson, Ulrika Bornetun
16 --  Creation date:    1991-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: xtmMsgSelect.c, Version: 1.1, Date: 95/02/18 15:52:33";
32 
33 
34 /*----------------------------------------------------------------------------
35 --  Include files
36 ----------------------------------------------------------------------------*/
37 
38 #include <string.h>
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <sys/types.h>
42 #include <sys/stat.h>
43 
44 #include <X11/Intrinsic.h>
45 #include <X11/Shell.h>
46 
47 #include <Xm/Protocols.h>
48 
49 #include <Xm/Xm.h>
50 #include <Xm/List.h>
51 #include <Xm/RowColumn.h>
52 
53 #include "System.h"
54 #include "DirList.h"
55 #include "Message.h"
56 #include "TimDate.h"
57 
58 #include "msgXdiary.h"
59 #include "xtmGlobal.h"
60 #include "xtmCalDb.h"
61 #include "xtmCustBase.h"
62 #include "xtmDbTools.h"
63 #include "xtmFormat.h"
64 #include "xtmHelp.h"
65 #include "xtmIcons.h"
66 #include "xtmMsgRead.h"
67 #include "xtmTools.h"
68 #include "xitError.h"
69 #include "xitTools.h"
70 #include "xtmMsgSelect.h"
71 
72 
73 /*----------------------------------------------------------------------------
74 --  Macro definitions
75 ----------------------------------------------------------------------------*/
76 
77 /* Local widgets in the message select window. */
78 #define menuBr              dataLocalW[  0 ]
79 #define msgLi               dataLocalW[  1 ]
80 #define msgboxLa            dataLocalW[  2 ]
81 
82 
83 /*----------------------------------------------------------------------------
84 --  Type declarations
85 ----------------------------------------------------------------------------*/
86 
87 
88 /* Record describing one instance of the message select window. */
89 typedef struct {
90 
91   /* Application wide data. */
92   XTM_GL_BASE_DATA_REF  appl_data_ref;
93 
94   /* Callback and user data to inform our creator of specific actions. */
95   XTM_ML_ACTION_CB  actionCB;
96   void              *user_data;
97 
98   /* Handle to read message. */
99   XTM_MR_HANDLE  read_handle;
100 
101   /* Select window. */
102   Widget  selectW;
103 
104 } SEL_REC, *SEL_REC_REF;
105 
106 
107 /*----------------------------------------------------------------------------
108 --  Global definitions
109 ----------------------------------------------------------------------------*/
110 
111 /* Name of module. */
112 static char  *module_name = "xtmMsgSelect";
113 
114 /* IDs for the help windows. */
115 static char  *select_window_id = "MsgSelect";
116 
117 
118 /*----------------------------------------------------------------------------
119 --  Function prototypes
120 ----------------------------------------------------------------------------*/
121 
122 static void
123   closeCB( Widget       widget,
124            SEL_REC_REF  sel_ref,
125            XtPointer    call_data );
126 
127 static Widget
128   createSelectWindow( Widget       parent,
129                       SEL_REC_REF  sel_ref );
130 
131 static void
132   deleteCB( Widget       widget,
133             SEL_REC_REF  sel_ref,
134             XtPointer    call_data );
135 
136 static void
137   deleteMessageCB( Widget       widget,
138                    SEL_REC_REF  sel_ref,
139                    XtPointer    call_data );
140 
141 static void
142   destroyCB( Widget       widget,
143              SEL_REC_REF  sel_ref,
144              XtPointer    call_data );
145 
146 static void
147   infoCB( Widget                     widget,
148           SEL_REC_REF                sel_ref,
149           XmRowColumnCallbackStruct  *call_data );
150 
151 static void
152   msgListCB( Widget       widget,
153              SEL_REC_REF  sel_ref,
154              XtPointer    call_data );
155 
156 static void
157   readCB( Widget       widget,
158           SEL_REC_REF  sel_ref,
159           XtPointer    call_data );
160 
161 static void
162   redisplayCB( Widget       widget,
163                SEL_REC_REF  sel_ref,
164                XtPointer    call_data );
165 
166 static void
167   setActions( SEL_REC_REF  sel_ref );
168 
169 static void
170   setSelectWindowValues( SEL_REC_REF  sel_ref );
171 
172 
173 
174 /*----------------------------------------------------------------------------
175 --  Functions
176 ----------------------------------------------------------------------------*/
177 
178 XTM_ML_HANDLE
xtmMlInitialize(XTM_GL_BASE_DATA_REF appl_data_ref,Widget parent,XTM_ML_ACTION_CB actionCB,void * user_data)179   xtmMlInitialize( XTM_GL_BASE_DATA_REF  appl_data_ref,
180                    Widget                parent,
181                    XTM_ML_ACTION_CB      actionCB,
182                    void                  *user_data )
183 {
184 
185   /* Variables. */
186   SEL_REC_REF  sel_ref;
187 
188 
189   /* Code. */
190 
191   /* Create and initialize our private data. */
192   sel_ref = SysNew( SEL_REC );
193   if( sel_ref == NULL )
194     return( NULL );
195 
196   sel_ref -> appl_data_ref = appl_data_ref;
197   sel_ref -> selectW       = NULL;
198   sel_ref -> actionCB      = actionCB;
199   sel_ref -> user_data     = user_data;
200   sel_ref -> read_handle   = NULL;
201 
202 
203   /* Create the message select window. */
204   sel_ref -> selectW = createSelectWindow( parent, sel_ref );
205   if( sel_ref -> selectW == NULL ) {
206     SysFree( sel_ref );
207 
208     return( NULL );
209   }
210 
211 
212   return( (XTM_ML_HANDLE) sel_ref );
213 
214 } /* xtmMlInitialize */
215 
216 
217 /*----------------------------------------------------------------------*/
218 
219 void
xtmMlDestroy(XTM_ML_HANDLE sel_handle)220   xtmMlDestroy( XTM_ML_HANDLE  sel_handle )
221 {
222 
223   /* Variables. */
224   SEL_REC_REF  sel_ref;
225 
226 
227   /* Code. */
228 
229   if( sel_handle == NULL )
230     return;
231 
232   /* Our private data. */
233   sel_ref = (SEL_REC_REF) sel_handle;
234 
235 
236   /* Get rid of all windows. */
237   if( sel_ref -> selectW != NULL )
238     XtDestroyWidget( sel_ref -> selectW );
239 
240 
241   return;
242 
243 } /* xtmMlDestroy */
244 
245 
246 /*---------------------------------------------------------------------------*/
247 
248 void
xtmMlSelectMessage(XTM_ML_HANDLE sel_handle)249   xtmMlSelectMessage( XTM_ML_HANDLE  sel_handle )
250 {
251 
252   /* Variables. */
253   SEL_REC_REF  sel_ref;
254 
255 
256   /* Code. */
257 
258   /* Our private data. */
259   sel_ref = (SEL_REC_REF) sel_handle;
260 
261 
262   /* Make sure the editor window is visable and set values. */
263   setSelectWindowValues( sel_ref );
264 
265   XtPopup( sel_ref -> selectW, XtGrabNone );
266 
267   XRaiseWindow( XtDisplay( sel_ref -> selectW ),
268                 XtWindow(  sel_ref -> selectW ) );
269   XtMapWidget( sel_ref -> selectW );
270 
271 
272   return;
273 
274 } /* xtmMseSelectMessage */
275 
276 
277 /*----------------------------------------------------------------------*/
278 
279 static Widget
createSelectWindow(Widget parent,SEL_REC_REF sel_ref)280   createSelectWindow( Widget       parent,
281                       SEL_REC_REF  sel_ref )
282 {
283 
284   /* Variables. */
285   int       index;
286   char      *char_ref;
287   Arg       args[ 10 ];
288   Cardinal  n;
289   Widget    dataLocalW[ 3 ];
290   Widget    menuCasc[ 2 ];
291   Widget    menuHelpBu[ 6 ];
292   Widget    menuFileBu[ 1 ];
293   Widget    pulldownMenu[ 2 ];
294   Widget    msgSelTl;
295   Widget    tempW;
296   Widget    workFo;
297 
298   static char  *pull_downs[] = { "pdown1", "pdown2" };
299 
300   static XIT_CASCADE_STRUCT menupane[] = {
301     { "", "", "FilePane" },
302     { "", "", "HelpPane" },
303   };
304 
305   static XIT_MENU_BUTTON_STRUCT file_casc[] = {
306     { "", "", NULL, "CloseBu", True, False, False },
307   };
308 
309   static XIT_MENU_BUTTON_STRUCT help_casc[] = {
310     { "", "", NULL, "ContextBu", True, False, False },
311     { "", "", NULL, "WindowsBu", True, False, False },
312     { "", "", NULL, "KeysBu",    True, False, False },
313     { "", "", NULL, "IndexBu",   True, False, False },
314     { "", "", NULL, "HelpBu",    True, False, False },
315     { "", "", NULL, "VersionBu", True, False, False },
316   };
317 
318   static XIT_ACTION_AREA_ITEM  action_buttons[] = {
319     { "", readCB,      NULL },
320     { "", deleteCB,    NULL },
321     { "", redisplayCB, NULL },
322     { "", closeCB,     NULL },
323   };
324 
325 
326   /* Code. */
327 
328   /* Initialize the menu items. */
329   action_buttons[ 0 ].label = msgGetText( MXDI_READ_LABEL );
330   action_buttons[ 0 ].data  = sel_ref;
331   action_buttons[ 1 ].label = msgGetText( MXDI_DELETE_LABEL );
332   action_buttons[ 1 ].data  = sel_ref;
333   action_buttons[ 2 ].label = msgGetText( MXDI_REDISPLAY_BUTTON );
334   action_buttons[ 2 ].data  = sel_ref;
335   action_buttons[ 3 ].label = msgGetText( MXDI_CLOSE_BUTTON );
336   action_buttons[ 3 ].data  = sel_ref;
337 
338   menupane[ 0 ].title    = msgGetText( MXDI_FILE_MENU );
339   menupane[ 0 ].mnemonic = msgGetText( MXDI_FILE_MENU_ACC );
340   menupane[ 1 ].title    = msgGetText( MXDI_HELP_MENU );
341   menupane[ 1 ].mnemonic = msgGetText( MXDI_HELP_MENU_ACC );
342 
343   file_casc[ 0 ].title    = msgGetText( MXDI_CLOSE_MENU );
344   file_casc[ 0 ].mnemonic = msgGetText( MXDI_CLOSE_MENU_ACC );
345 
346   help_casc[ 0 ].title    = msgGetText( MXDI_HELP_CONTEXT );
347   help_casc[ 0 ].mnemonic = msgGetText( MXDI_HELP_CONTEXT_ACC );
348   help_casc[ 1 ].title    = msgGetText( MXDI_HELP_WINDOWS );
349   help_casc[ 1 ].mnemonic = msgGetText( MXDI_HELP_WINDOWS_ACC );
350   help_casc[ 2 ].title    = msgGetText( MXDI_HELP_KEYS );
351   help_casc[ 2 ].mnemonic = msgGetText( MXDI_HELP_KEYS_ACC );
352   help_casc[ 3 ].title    = msgGetText( MXDI_HELP_INDEX );
353   help_casc[ 3 ].mnemonic = msgGetText( MXDI_HELP_INDEX_ACC );
354   help_casc[ 4 ].title    = msgGetText( MXDI_HELP_HELP );
355   help_casc[ 4 ].mnemonic = msgGetText( MXDI_HELP_HELP_ACC );
356   help_casc[ 5 ].title    = msgGetText( MXDI_HELP_VERSION );
357   help_casc[ 5 ].mnemonic = msgGetText( MXDI_HELP_VERSION_ACC );
358 
359 
360   /* Create a separate window. */
361   tempW = xitGetToplevelWidget( parent );
362 
363   msgSelTl = xitCreateToplevelDialog( tempW, "MsgSelTl",
364                                       0, 0,
365                                       action_buttons,
366                                       XtNumber( action_buttons ) );
367 
368   /* Create a separate window. */
369   char_ref = msgGetText( MXDI_RECEIVE_MSG_TITLE );
370 
371   n = 0;
372   XtSetArg( args[ n ], XmNtitle, char_ref ); n++;
373   XtSetValues( msgSelTl, args, n );
374 
375   char_ref = msgGetText( MXDI_RECEIVE_MSG_IC_TITLE );
376 
377   n = 0;
378   XtSetArg( args[ n ], XmNiconName, char_ref ); n++;
379   XtSetValues( msgSelTl, args, n );
380 
381   XtAddCallback( msgSelTl,  XmNdestroyCallback,
382                  (XtCallbackProc) destroyCB, (XtPointer) sel_ref );
383 
384 
385   /* Exit the application if this window is deleted. */
386   {
387     Atom  wm_delete_window;
388 
389     wm_delete_window = XmInternAtom( XtDisplay( msgSelTl ),
390                                      "WM_DELETE_WINDOW", False );
391 
392     XmAddWMProtocols( msgSelTl, &wm_delete_window, 1 );
393     XmAddWMProtocolCallback( msgSelTl, wm_delete_window,
394                              (XtCallbackProc) closeCB, (XtPointer) sel_ref );
395   } /* block */
396 
397 
398   /* Form to work in. */
399   workFo = XtNameToWidget( msgSelTl, "MsgSelTlBase.MsgSelTlFo" );
400 
401 
402   /* Create the menubar and menu cascades. */
403   n = 0;
404   menuBr = XmCreateMenuBar( workFo, "MenuBr", args, n );
405 
406   n = 0;
407   for( index = 0; index < XtNumber( pulldownMenu ); index++ )
408     pulldownMenu[ index ] = XmCreatePulldownMenu( menuBr,
409                                                   pull_downs[ index ],
410                                                   NULL, n );
411 
412   for( index = 0; index < XtNumber( menuCasc ); index++ )
413     menuCasc[ index ] = xitCreateCascadeButton( menuBr,
414                                                 pulldownMenu[ index ],
415                                                 &menupane[ index ] );
416 
417   /* The help button should be placed to the right. */
418   index = XtNumber( menuCasc ) - 1;
419   n     = 0;
420   XtSetArg( args[ n ], XmNmenuHelpWidget, menuCasc[ index ] ); n++;
421   XtSetValues( menuBr, args, n );
422 
423 
424   /* Create the file menu. */
425   for( index = 0; index < XtNumber( menuFileBu ); index++ )
426     menuFileBu[ index ] = xitCreateMenuPushButton( pulldownMenu[ 0 ],
427                                                    &file_casc[ index ] );
428   XtAddCallback( menuFileBu[ 0 ], XmNactivateCallback,
429                  (XtCallbackProc) closeCB, (XtPointer) sel_ref );
430 
431 
432   /* Create the help menu. */
433   XtAddCallback( pulldownMenu[ 1 ], XmNentryCallback,
434                  (XtCallbackProc) infoCB, (XtPointer) sel_ref );
435 
436   for( index = 0; index < XtNumber( menuHelpBu ); index++ ) {
437     menuHelpBu[ index ] = xitCreateMenuPushButton( pulldownMenu[ 1 ],
438                                                    &help_casc[ index ] );
439 
440     XtAddCallback( menuHelpBu[ index ], XmNactivateCallback,
441                    (XtCallbackProc) infoCB, (XtPointer)(intptr_t)index );
442   }
443 
444   /* We can't do context sensitive help. */
445   XtSetSensitive( menuHelpBu[ 0 ], False );
446 
447 
448   /* Create the mailbox list. */
449   msgboxLa = xitCreateLabel( workFo, "MsgboxLa",
450                              msgGetText( MXDI_MSG_BOX_LABEL ), -1 );
451 
452   n = 0;
453   XtSetArg( args[ n ], XmNlistSizePolicy,         XmRESIZE_IF_POSSIBLE ); n++;
454   XtSetArg( args[ n ], XmNselectionPolicy,        XmEXTENDED_SELECT ); n++;
455   XtSetArg( args[ n ], XmNscrollBarDisplayPolicy, XmSTATIC ); n++;
456   XtSetArg( args[ n ], XmNlistMarginHeight,       5 ); n++;
457   XtSetArg( args[ n ], XmNlistMarginWidth,        5 ); n++;
458   msgLi = XmCreateScrolledList( workFo, "MsgLi", args, n );
459 
460   XtAddCallback( msgLi, XmNsingleSelectionCallback,
461                  (XtCallbackProc) msgListCB, (XtPointer) sel_ref );
462   XtAddCallback( msgLi, XmNextendedSelectionCallback,
463                  (XtCallbackProc) msgListCB, (XtPointer) sel_ref );
464   XtAddCallback( msgLi, XmNdefaultActionCallback,
465                  (XtCallbackProc) readCB, (XtPointer) sel_ref );
466 
467 
468   /* Place the main elements together. */
469   xitAttachWidget( menuBr,
470                    XmATTACH_FORM, NULL, XmATTACH_FORM, NULL,
471                    XmATTACH_FORM, NULL, XmATTACH_NONE, NULL );
472   xitAttachWidget( msgboxLa,
473                    XmATTACH_WIDGET, menuBr, XmATTACH_FORM, NULL,
474                    XmATTACH_NONE,   NULL,   XmATTACH_NONE, NULL );
475   xitAttachWidget( XtParent( msgLi ),
476                    XmATTACH_WIDGET, msgboxLa, XmATTACH_FORM, NULL,
477                    XmATTACH_FORM,   NULL,     XmATTACH_NONE, NULL );
478 
479 
480   /* Make sure there is enough space between the children. */
481   n = 0;
482   XtSetArg( args[ n ], XmNtopOffset,    5 ); n++;
483   XtSetArg( args[ n ], XmNleftOffset,   5 ); n++;
484   XtSetArg( args[ n ], XmNrightOffset,  5 ); n++;
485   XtSetArg( args[ n ], XmNbottomOffset, 5 ); n++;
486   XtSetValues( msgboxLa,          args, n );
487   XtSetValues( XtParent( msgLi ), args, n );
488 
489 
490   /* Manage all the children. */
491   XtManageChildren( menuCasc,   XtNumber( menuCasc ) );
492   XtManageChildren( menuHelpBu, XtNumber( menuHelpBu ) );
493   XtManageChildren( menuFileBu, XtNumber( menuFileBu ) );
494 
495   xitManageChildren( dataLocalW, XtNumber( dataLocalW ) );
496 
497 
498   /* Set icon for this window. */
499   xtmIcSetSimpleIcon( msgSelTl, workFo, XTM_IC_ICON_MAIL );
500 
501 
502   /* Make the final attachments. */
503   n = 0;
504   XtSetArg( args[ n ], XmNbottomAttachment, XmATTACH_FORM ); n++;
505   XtSetValues( XtParent( msgLi ), args, n );
506 
507 
508   return( msgSelTl );
509 
510 } /* createSelectWindow */
511 
512 
513 /*----------------------------------------------------------------------*/
514 
515 static void
setActions(SEL_REC_REF sel_ref)516   setActions( SEL_REC_REF  sel_ref )
517 {
518 
519   /* Variables. */
520   Boolean   sensitive;
521   int       item_count;
522   int       selected_item_count;
523   Arg       args[ 5 ];
524   Cardinal  n;
525   Widget    baseW;
526   Widget    mainW;
527   Widget    tempW;
528 
529 
530   /* Code. */
531 
532   baseW = XtNameToWidget( sel_ref -> selectW, "MsgSelTlBase" );
533   mainW = XtNameToWidget( sel_ref -> selectW, "MsgSelTlBase.MsgSelTlFo" );
534 
535 
536   /* Do we have a selected message? */
537   tempW = XtNameToWidget( mainW, "MsgLiSW.MsgLi" );
538 
539   n = 0;
540   XtSetArg( args[ n ], XmNitemCount, &item_count ); n++;
541   XtSetArg( args[ n ], XmNselectedItemCount, &selected_item_count ); n++;
542   XtGetValues( tempW, args, n );
543 
544   if( selected_item_count < 1 || item_count < 1 )
545     sensitive = False;
546   else
547     sensitive = True;
548 
549 
550   /* Set sensitivity for action buttons. */
551   tempW = XtNameToWidget( baseW, "Bu1" );
552   XtSetSensitive( tempW, sensitive );
553 
554   tempW = XtNameToWidget( baseW, "Bu2" );
555   XtSetSensitive( tempW, sensitive );
556 
557 
558   return;
559 
560 } /* setActions */
561 
562 
563 /*----------------------------------------------------------------------*/
564 
565 static void
setSelectWindowValues(SEL_REC_REF sel_ref)566   setSelectWindowValues( SEL_REC_REF  sel_ref )
567 {
568 
569   /* Variables. */
570   int                   index;
571   int                   index1;
572   int                   items;
573   int                   status;
574   char                  buffer[ 51 ];
575   char                  date[ 20 ];
576   char                  filename[ 150 ];
577   char                  file_pattern[ 100 ];
578   char                  message_dir[ 150 ];
579   Arg                   args[ 5 ];
580   Cardinal              n;
581   Widget                mainW;
582   Widget                tempW;
583   XmString              list_items[ 100 ];
584   XTM_GL_BASE_DATA_REF  appl_data_ref;
585   XTM_CD_CAL_INFO       default_db;
586   struct stat           file_info;
587 
588 
589   /* Code. */
590 
591   appl_data_ref = sel_ref -> appl_data_ref;
592 
593   mainW = XtNameToWidget( sel_ref -> selectW, "MsgSelTlBase.MsgSelTlFo" );
594 
595 
596   /* Messages are in the default database. */
597   (void) xtmCdFetchDefaultDb( appl_data_ref -> custom_data -> cal_db_handle,
598                               &default_db, NULL );
599 
600 
601   /* Find the message directory. */
602   sprintf( message_dir, "%s/Message", default_db.directory );
603 
604   status = stat( message_dir, &file_info );
605   if( status != 0 )
606     sprintf( message_dir, "%s", default_db.directory );
607 
608 
609   /* Fetch all message files. */
610   index = 0;
611   sprintf( file_pattern, "%s/%s_*_*", message_dir, XTM_DB_MESSAGE_FILE );
612 
613   status = DirFindFirst( file_pattern, filename );
614   while( status == 0 ) {
615 
616     int           id;
617     char          user[ 51 ];
618     char          *char_ref;
619     TIM_TIME_REF  tmp_time;
620 
621     /* Message file information. */
622     status = stat( filename, &file_info );
623 
624     /* Split into user, number and id. */
625     char_ref = strrchr( filename, '/' );
626     if( char_ref != NULL )
627       char_ref++;
628     else
629       char_ref = filename;
630 
631     items = sscanf( char_ref, "%[^_]_%[^_]_%d", buffer, user, &id );
632     if( items == 3 ) {
633 
634       /* Date of the message. */
635       tmp_time = TimLocalTime( (TIM_TIME_REF) file_info.st_mtime );
636 
637       xtmFoFormatDate( tmp_time, date, sizeof( date ) );
638 
639       /* Create the message line. */
640       sprintf( buffer, "%s %-15.15s  %d", date, user, id );
641 
642       list_items[ index ] = XmStringCreate( buffer, CS );
643       index++;
644 
645     } /* if */
646 
647     /* Next Message. */
648     status = DirFindNext( filename );
649 
650   } /* while */
651 
652   /* Put the messages in the list. */
653   tempW = XtNameToWidget( mainW, "MsgLiSW.MsgLi" );
654 
655   n = 0;
656   XtSetArg( args[ n ], XmNitems, list_items ); n++;
657   XtSetArg( args[ n ], XmNitemCount, index ); n++;
658   XtSetValues( tempW, args, n );
659 
660   XmListDeselectAllItems( tempW );
661 
662   /* Free allocated memory. */
663   for( index1 = 0; index1 < index; index1++ )
664     XmStringFree( list_items[ index1 ] );
665 
666 
667   /* Set active buttons. */
668   setActions( sel_ref );
669 
670 
671   return;
672 
673 } /* setSelectWindowValues */
674 
675 
676 /*----------------------------------------------------------------------*/
677 
678 static void
closeCB(Widget widget,SEL_REC_REF sel_ref,XtPointer call_data)679   closeCB( Widget       widget,
680            SEL_REC_REF  sel_ref,
681            XtPointer    call_data )
682 {
683 
684   /* Code. */
685 
686   XtPopdown( sel_ref -> selectW );
687 
688 
689   return;
690 
691 } /* closeCB */
692 
693 
694 /*----------------------------------------------------------------------*/
695 
696 static void
deleteCB(Widget widget,SEL_REC_REF sel_ref,XtPointer call_data)697   deleteCB( Widget       widget,
698             SEL_REC_REF  sel_ref,
699             XtPointer    call_data )
700 {
701 
702   /* Variables. */
703   int       selected_item_count;
704   Arg       args[ 5 ];
705   Cardinal  n;
706   Widget    mainW;
707   Widget    tempW;
708 
709 
710   /* Code. */
711 
712   mainW = XtNameToWidget( sel_ref -> selectW, "MsgSelTlBase.MsgSelTlFo" );
713 
714 
715   /* Fetch the selected message(s). */
716   tempW = XtNameToWidget( mainW, "MsgLiSW.MsgLi" );
717 
718   n = 0;
719   XtSetArg( args[ n ], XmNselectedItemCount, &selected_item_count ); n++;
720   XtGetValues( tempW, args, n );
721 
722   if( selected_item_count < 1 )
723     return;
724 
725 
726   /* Does the user confirm? */
727   if( sel_ref -> appl_data_ref -> custom_data -> confirm_actions ) {
728 
729     tempW = xitCreateQuestionDialog(
730               sel_ref -> selectW, "QuestionDialog",
731               msgGetText( MXDI_QUESTION_MESSAGE_LABEL ),
732               msgGetText( MXDI_DELETE_MESSAGE_CONF ),
733               deleteMessageCB, sel_ref,
734               NULL, NULL );
735 
736     return;
737   }
738 
739   /* Remove the message. */
740   deleteMessageCB( widget, sel_ref, NULL );
741 
742 
743   return;
744 
745 } /* deleteCB */
746 
747 
748 /*----------------------------------------------------------------------*/
749 
750 static void
deleteMessageCB(Widget widget,SEL_REC_REF sel_ref,XtPointer call_data)751   deleteMessageCB( Widget       widget,
752                    SEL_REC_REF  sel_ref,
753                    XtPointer    call_data )
754 {
755 
756   /* Variables. */
757   int                   index;
758   int                   msg_id;
759   int                   selected_item_count;
760   char                  dummy[ 51 ];
761   char                  *buffer_ref;
762   Arg                   args[ 5 ];
763   Cardinal              n;
764   Widget                mainW;
765   Widget                tempW;
766   XmString              *selected_items;
767   XTM_DB_STATUS         db_status;
768   XTM_GL_BASE_DATA_REF  appl_data_ref;
769   XTM_CD_CAL_INFO       default_db;
770 
771 
772   /* Code. */
773 
774   appl_data_ref = sel_ref -> appl_data_ref;
775 
776   mainW = XtNameToWidget( sel_ref -> selectW, "MsgSelTlBase.MsgSelTlFo" );
777 
778 
779   /* The default database contains the messages. */
780   (void) xtmCdFetchDefaultDb( appl_data_ref -> custom_data -> cal_db_handle,
781                               &default_db, NULL );
782 
783 
784   /* Fetch the selected messages. */
785   tempW = XtNameToWidget( mainW, "MsgLiSW.MsgLi" );
786 
787   n = 0;
788   XtSetArg( args[ n ], XmNselectedItemCount, &selected_item_count ); n++;
789   XtSetArg( args[ n ], XmNselectedItems,     &selected_items ); n++;
790   XtGetValues( tempW, args, n );
791 
792 
793   /* Delete all selected messages. */
794   for( index = 0; index < selected_item_count; index++ ) {
795 
796     buffer_ref = xitStringGetString( *(selected_items + index), CS );
797 
798     sscanf( buffer_ref, "%[^ ] %[^ ] %d", dummy, dummy, &msg_id );
799     SysFree( buffer_ref );
800 
801     /* Delete the message. */
802     db_status = xtmDbDeleteMessage( default_db.directory, msg_id );
803 
804   } /* loop */
805 
806 
807   /* Update the message box. */
808   setSelectWindowValues( sel_ref );
809 
810 
811   return;
812 
813 } /* deleteMessageCB */
814 
815 
816 /*----------------------------------------------------------------------*/
817 
818 static void
destroyCB(Widget widget,SEL_REC_REF sel_ref,XtPointer call_data)819   destroyCB( Widget       widget,
820              SEL_REC_REF  sel_ref,
821              XtPointer    call_data )
822 {
823 
824   /* Code. */
825 
826   /* Do we have a user action callback registered? */
827   if( sel_ref -> actionCB != NULL )
828     (* sel_ref -> actionCB)( XTM_ML_REASON_DESTROY,
829                              sel_ref -> user_data );
830 
831 
832   /* Release the user data. */
833   SysFree( sel_ref );
834 
835 
836   return;
837 
838 } /* destroyCB */
839 
840 
841 /*----------------------------------------------------------------------*/
842 
843 static void
infoCB(Widget widget,SEL_REC_REF sel_ref,XmRowColumnCallbackStruct * call_data)844   infoCB( Widget                     widget,
845           SEL_REC_REF                sel_ref,
846           XmRowColumnCallbackStruct  *call_data )
847 {
848 
849   /* Code. */
850 
851   xtmHlDisplayHelp( sel_ref -> appl_data_ref -> info_handle,
852                     (intptr_t) call_data -> data,
853                     select_window_id, "" );
854 
855   return;
856 
857 } /* infoCB */
858 
859 
860 /*----------------------------------------------------------------------*/
861 
862 static void
msgListCB(Widget widget,SEL_REC_REF sel_ref,XtPointer call_data)863   msgListCB( Widget       widget,
864              SEL_REC_REF  sel_ref,
865              XtPointer    call_data )
866 {
867 
868   /* Code. */
869 
870   setActions( sel_ref );
871 
872 
873   return;
874 
875 } /* msgListCB */
876 
877 
878 /*----------------------------------------------------------------------*/
879 
880 static void
readCB(Widget widget,SEL_REC_REF sel_ref,XtPointer call_data)881   readCB( Widget       widget,
882           SEL_REC_REF  sel_ref,
883           XtPointer    call_data )
884 {
885 
886   /* Variables. */
887   int       selected_item_count;
888   int       msg_id;
889   char      dummy[ 51 ];
890   char      *buffer_ref;
891   Arg       args[ 5 ];
892   Cardinal  n;
893   Widget    mainW;
894   Widget    tempW;
895   XmString  *selected_items;
896 
897 
898   /* Code. */
899 
900   mainW = XtNameToWidget( sel_ref -> selectW, "MsgSelTlBase.MsgSelTlFo" );
901 
902 
903   /* Fetch the selected message (if more selected, use the first). */
904   tempW = XtNameToWidget( mainW, "MsgLiSW.MsgLi" );
905 
906   n = 0;
907   XtSetArg( args[ n ], XmNselectedItemCount, &selected_item_count ); n++;
908   XtSetArg( args[ n ], XmNselectedItems,     &selected_items ); n++;
909   XtGetValues( tempW, args, n );
910 
911   if( selected_item_count < 1 )
912     return;
913 
914 
915   /* Fetch the message number. */
916   buffer_ref = xitStringGetString( *selected_items, CS );
917 
918   sscanf( buffer_ref, "%[^ ] %[^ ] %d", dummy, dummy, &msg_id );
919   SysFree( buffer_ref );
920 
921 
922   /* Initialize the read window. */
923   if( sel_ref -> read_handle == NULL )
924     sel_ref -> read_handle = xtmMrInitialize( sel_ref -> appl_data_ref,
925                                               sel_ref -> selectW );
926 
927   /* Display the message. */
928   xtmMrReadMessage( sel_ref -> read_handle, msg_id );
929 
930 
931   return;
932 
933 } /* readCB */
934 
935 
936 /*----------------------------------------------------------------------*/
937 
938 static void
redisplayCB(Widget widget,SEL_REC_REF sel_ref,XtPointer call_data)939   redisplayCB( Widget       widget,
940                SEL_REC_REF  sel_ref,
941                XtPointer    call_data )
942 {
943 
944   /* Code. */
945 
946   setSelectWindowValues( sel_ref );
947 
948 
949   return;
950 
951 } /* redisplayCB */
952