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