1 /*---------------------------------------------------------------------------- 2 -- 3 -- Module: XmUbTimeBox 4 -- 5 -- Project: XmUb - Ulle's Motif widgets 6 -- System: 7 -- Subsystem: <> 8 -- Function block: <> 9 -- 10 -- Description: 11 -- This is the implementation of the widget. 12 -- 13 -- Filename: XmUbTimeB.c 14 -- 15 -- Authors: Roger Larsson, Ulrika Bornetun 16 -- Creation date: 1993-09-12 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: XmUbTimeB.c, Version: 1.1, Date: 95/02/18 15:10:15"; 32 33 34 /*---------------------------------------------------------------------------- 35 -- Include files 36 ----------------------------------------------------------------------------*/ 37 38 #include <stdio.h> 39 #include <string.h> 40 #include <X11/Intrinsic.h> 41 #include <X11/StringDefs.h> 42 #include <Xm/XmP.h> 43 44 #if XmVersion > 1001 45 #include <Xm/AtomMgr.h> 46 #include <Xm/DragDrop.h> 47 #endif 48 49 #include <Xm/CascadeB.h> 50 #include <Xm/Form.h> 51 #include <Xm/PushB.h> 52 #include <Xm/RowColumn.h> 53 #include <Xm/Separator.h> 54 #include <Xm/Text.h> 55 #include <Xm/Protocols.h> 56 57 #include "XmUbMonthD.h" 58 #include "XmUbTimeSl.h" 59 60 /* Rogge's tools. */ 61 #include "TimDate.h" 62 63 /* Private widget header file. */ 64 #include "XmUbTimeBP.h" 65 66 /* Drag and drop. */ 67 #if XmVersion > 1001 68 #include "XmUbDragDrop.h" 69 #endif 70 71 /*---------------------------------------------------------------------------- 72 -- Macro definitions 73 ----------------------------------------------------------------------------*/ 74 75 #ifdef MAX 76 #undef MAX 77 #endif 78 79 #ifdef MIN 80 #undef MIN 81 #endif 82 83 #define MAX( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) 84 #define MIN( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) 85 86 #define DATE_FIELD_COLUMNS 10 87 #define TIME_FIELD_COLUMNS 8 88 #define TIME_STRING_BUFFER_LEN 25 89 #define TEXT_BUFFER_LENGTH 20 90 91 /* Resource converters. */ 92 #define XmRwidgetFormatType "TimeBoxWidgetFormatType" 93 #define XmRmenuPositionType "TimeBoxMenuPositionType" 94 95 96 /* Constants. */ 97 #define MAX_NO_DEFAULT_MENU_ITEMS 15 98 #define MAX_PATTERN_LENGTH 30 99 100 101 /* General error codes. */ 102 #define XmUbTB_CHILD_ERROR -1 103 104 /*---------------------------------------------------------------------------- 105 -- Type declarations 106 ----------------------------------------------------------------------------*/ 107 108 typedef struct { 109 110 Dimension width; 111 Dimension height; 112 Position x; 113 Position y; 114 115 } KidDimensionRec; 116 117 /*---------------------------------------------------------------------------- 118 -- Global definitions 119 ----------------------------------------------------------------------------*/ 120 121 /* Flag is set when the application context dependent things have been done. */ 122 static Boolean context_dependent_done = False; 123 124 static Atom protocol_atom; 125 static Atom delete_atom; 126 127 /* Internal Motif functions (how do we know about this....?) */ 128 extern void 129 _XmBackgroundColorDefault(); 130 extern void 131 _XmForegroundColorDefault(); 132 133 /* Default scanning strings for date/time completion. */ 134 static char default_day_marker[] = "dD"; 135 static char default_hour_marker[] = "hH"; 136 static char default_minute_marker[] = "mM"; 137 static char default_month_marker[] = "mM"; 138 static char default_week_marker[] = "wW"; 139 static char default_year_marker[] = "yY"; 140 141 /* Default string for default action when completion failed. */ 142 static char default_completion_failed_string[] = "??"; 143 144 /* Default dialog titles. */ 145 static char default_date_selection_title[] = "Select a date"; 146 static char default_time_selection_title[] = "Select a time"; 147 148 /* Default dialog labels. */ 149 static char default_ok_string[] = "Ok"; 150 static char default_cancel_string[] = "Cancel"; 151 static char default_year_string[] = "Year"; 152 static char default_month_string[] = "Month"; 153 static char default_week_string[] = "W"; 154 155 /* The time box resource list. */ 156 static XtResource resources[] = { 157 { 158 XmNactivateCallback, 159 XmCCallback, 160 XmRCallback, sizeof( XtCallbackList ), 161 XtOffset( XmUbTimeBoxWidget, tbox.activate_callback ), 162 XmRCallback, 163 NULL 164 }, 165 { 166 XmNvalueChangedCallback, 167 XmCCallback, 168 XmRCallback, sizeof( XtCallbackList ), 169 XtOffset( XmUbTimeBoxWidget, tbox.value_changed_callback ), 170 XmRCallback, 171 NULL 172 }, 173 { 174 XmUbNtboxPopupSelectionCallback, 175 XmCCallback, 176 XmRCallback, sizeof( XtCallbackList ), 177 XtOffset( XmUbTimeBoxWidget, tbox.popup_selection_callback ), 178 XmRCallback, 179 NULL 180 }, 181 { 182 XmNcancelLabelString, 183 XmCCancelLabelString, 184 XmRXmString, sizeof( XmString ), 185 XtOffset( XmUbTimeBoxWidget, tbox.cancel_label ), 186 XtRImmediate, 187 (XtPointer) NULL 188 }, 189 { 190 XmNmarginHeight, 191 XmCMarginHeight, 192 XtRDimension, sizeof( Dimension ), 193 XtOffset( XmUbTimeBoxWidget, tbox.margin_height ), 194 XtRImmediate, 195 (XtPointer) 0 196 }, 197 { 198 XmNmarginWidth, 199 XmCMarginWidth, 200 XtRDimension, sizeof( Dimension ), 201 XtOffset( XmUbTimeBoxWidget, tbox.margin_width ), 202 XtRImmediate, 203 (XtPointer) 0 204 }, 205 { 206 XmNokLabelString, 207 XmCOkLabelString, 208 XmRXmString, sizeof( XmString ), 209 XtOffset( XmUbTimeBoxWidget, tbox.ok_label ), 210 XtRImmediate, 211 (XtPointer) NULL 212 }, 213 { 214 XmNorientation, 215 XmCOrientation, 216 XmROrientation, sizeof( unsigned char ), 217 XtOffset( XmUbTimeBoxWidget, tbox.orientation ), 218 XtRImmediate, 219 (XtPointer) XmHORIZONTAL 220 }, 221 { 222 XmUbNtboxCodeDay, 223 XmUbCTboxCodeDay, 224 XmRString, sizeof( char* ), 225 XtOffset( XmUbTimeBoxWidget, tbox.day_marker ), 226 XtRImmediate, 227 (XtPointer) NULL 228 }, 229 { 230 XmUbNtboxCodeHour, 231 XmUbCTboxCodeHour, 232 XmRString, sizeof( char* ), 233 XtOffset( XmUbTimeBoxWidget, tbox.hour_marker ), 234 XtRImmediate, 235 (XtPointer) NULL 236 }, 237 { 238 XmUbNtboxCodeMinute, 239 XmUbCTboxCodeMinute, 240 XmRString, sizeof( char* ), 241 XtOffset( XmUbTimeBoxWidget, tbox.minute_marker ), 242 XtRImmediate, 243 (XtPointer) NULL 244 }, 245 { 246 XmUbNtboxCodeMonth, 247 XmUbCTboxCodeMonth, 248 XmRString, sizeof( char* ), 249 XtOffset( XmUbTimeBoxWidget, tbox.month_marker ), 250 XtRImmediate, 251 (XtPointer) NULL 252 }, 253 { 254 XmUbNtboxCodeWeek, 255 XmUbCTboxCodeWeek, 256 XmRString, sizeof( char* ), 257 XtOffset( XmUbTimeBoxWidget, tbox.week_marker ), 258 XtRImmediate, 259 (XtPointer) NULL 260 }, 261 { 262 XmUbNtboxCodeYear, 263 XmUbCTboxCodeYear, 264 XmRString, sizeof( char* ), 265 XtOffset( XmUbTimeBoxWidget, tbox.year_marker ), 266 XtRImmediate, 267 (XtPointer) NULL 268 }, 269 { 270 XmUbNtboxCompletionCallback, 271 XmCCallback, 272 XmRCallback, sizeof( XtCallbackList ), 273 XtOffset( XmUbTimeBoxWidget, tbox.completion_callback ), 274 XmRCallback, 275 NULL 276 }, 277 { 278 XmUbNtboxComponentTogether, 279 XmUbCTboxComponentTogether, 280 XtRBoolean, sizeof( Boolean ), 281 XtOffset( XmUbTimeBoxWidget, tbox.component_together ), 282 XtRImmediate, 283 (XtPointer) True 284 }, 285 { 286 XmUbNtboxDateSelectionTitle, 287 XmUbCTboxDateSelectionTitle, 288 XtRString, sizeof( String ), 289 XtOffset( XmUbTimeBoxWidget, tbox.date_selection_title ), 290 XtRImmediate, 291 (XtPointer) NULL 292 }, 293 { 294 XmUbNtboxDestroyDialogs, 295 XmUbCTboxDestroyDialogs, 296 XtRBoolean, sizeof( Boolean ), 297 XtOffset( XmUbTimeBoxWidget, tbox.destroy_dialogs ), 298 XtRImmediate, 299 (XtPointer) True 300 }, 301 { 302 XmUbNtboxFieldSpacing, 303 XmCSpacing, 304 XtRDimension, sizeof( Dimension ), 305 XtOffset( XmUbTimeBoxWidget, tbox.field_spacing ), 306 XtRImmediate, 307 (XtPointer) 2 308 }, 309 { 310 XmUbNtboxFormat, 311 XmUbCTboxFormat, 312 XmRwidgetFormatType, sizeof( widgetFormatType ), 313 XtOffset( XmUbTimeBoxWidget, tbox.widget_format ), 314 XtRImmediate, 315 (XtPointer) XmUbTB_FORMAT_DTDT 316 }, 317 { 318 XmUbNtboxMenuEnabled, 319 XmUbCTboxMenuEnabled, 320 XtRBoolean, sizeof( Boolean ), 321 XtOffset( XmUbTimeBoxWidget, tbox.menu_enabled ), 322 XtRImmediate, 323 (XtPointer) True 324 }, 325 { 326 XmUbNtboxMenuItems, 327 XmUbCTboxMenuItems, 328 XtRPointer, sizeof( XmUbMenuItemRef ), 329 XtOffset( XmUbTimeBoxWidget, tbox.menu_items ), 330 XtRImmediate, 331 (XtPointer) NULL 332 }, 333 { 334 XmUbNtboxMenuLabel, 335 XmUbCTboxMenuLabel, 336 XmRXmString, sizeof( XmString ), 337 XtOffset( XmUbTimeBoxWidget, tbox.menu_label ), 338 XtRImmediate, 339 (XtPointer) NULL 340 }, 341 { 342 XmUbNtboxMenuPixmap, 343 XmUbCTboxMenuPixmap, 344 XmRPrimForegroundPixmap, sizeof( Pixmap ), 345 XtOffset( XmUbTimeBoxWidget, tbox.menu_pixmap ), 346 XtRImmediate, 347 (XtPointer) XmUNSPECIFIED_PIXMAP 348 }, 349 { 350 XmUbNtboxMenuPosition, 351 XmUbCTboxMenuPosition, 352 XmRmenuPositionType, sizeof( menuPositionType ), 353 XtOffset( XmUbTimeBoxWidget, tbox.menu_position ), 354 XtRImmediate, 355 (XtPointer) XmUbPOSITION_FIRST 356 }, 357 { 358 XmUbNtboxMenuSpacing, 359 XmCSpacing, 360 XtRDimension, sizeof( Dimension ), 361 XtOffset( XmUbTimeBoxWidget, tbox.menu_spacing ), 362 XtRImmediate, 363 (XtPointer) 4 364 }, 365 { 366 XmUbNtboxMonthLabel, 367 XmUbCTboxMonthLabel, 368 XmRXmString, sizeof( XmString ), 369 XtOffset( XmUbTimeBoxWidget, tbox.month_label ), 370 XtRImmediate, 371 (XtPointer) NULL 372 }, 373 { 374 XmUbNtboxNumItems, 375 XmUbCTboxNumItems, 376 XmRInt, sizeof( int ), 377 XtOffset( XmUbTimeBoxWidget, tbox.num_menu_items ), 378 XtRImmediate, 379 (XtPointer) 0 380 }, 381 { 382 XmUbNtboxRangeSpacing, 383 XmCSpacing, 384 XtRDimension, sizeof( Dimension ), 385 XtOffset( XmUbTimeBoxWidget, tbox.range_spacing ), 386 XtRImmediate, 387 (XtPointer) 10 388 }, 389 { 390 XmUbNtboxTimeSelectionTitle, 391 XmUbCTboxTimeSelectionTitle, 392 XtRString, sizeof( String ), 393 XtOffset( XmUbTimeBoxWidget, tbox.time_selection_title ), 394 XtRImmediate, 395 (XtPointer) NULL 396 }, 397 { 398 XmUbNtboxWeekLabel, 399 XmUbCTboxWeekLabel, 400 XmRXmString, sizeof( XmString ), 401 XtOffset( XmUbTimeBoxWidget, tbox.week_label ), 402 XtRImmediate, 403 (XtPointer) NULL 404 }, 405 { 406 XmUbNtboxYearLabel, 407 XmUbCTboxYearLabel, 408 XmRXmString, sizeof( XmString ), 409 XtOffset( XmUbTimeBoxWidget, tbox.year_label ), 410 XtRImmediate, 411 (XtPointer) NULL 412 }, 413 414 }; /* resources */ 415 416 /*---------------------------------------------------------------------------- 417 -- Function prototypes 418 ----------------------------------------------------------------------------*/ 419 420 /* Class methods. */ 421 static void 422 ClassInitialize(); 423 424 static void 425 ChangeManaged( Widget widget ); 426 427 static void 428 DeleteChild( Widget widget ); 429 430 static void 431 Destroy( Widget widget ); 432 433 static XtGeometryResult 434 GeometryManager( Widget widget, 435 XtWidgetGeometry *request, 436 XtWidgetGeometry *reply ); 437 438 static void 439 GetValuesHook( Widget w, 440 ArgList args, 441 Cardinal *num_args ); 442 443 static void 444 Initialize( Widget treq, 445 Widget tnew, 446 ArgList args, 447 Cardinal *num_args ); 448 449 static void 450 InsertChild( Widget widget ); 451 452 static void 453 PopupDateSelection( Widget widget ); 454 455 static void 456 PopupTimeSelection( Widget widget ); 457 458 static XtGeometryResult 459 QueryGeometry( Widget widget, 460 XtWidgetGeometry *proposed, 461 XtWidgetGeometry *answer ); 462 463 static void 464 Resize( Widget widget ); 465 466 static Boolean 467 SetValues( Widget current, 468 Widget request, 469 Widget new, 470 ArgList args, 471 Cardinal *num_args ); 472 473 /* Internal functions. */ 474 475 static void 476 ActivateCB( Widget tw, 477 XmUbTimeBoxWidget tbox, 478 XmAnyCallbackStruct *call_data ); 479 480 static void 481 AddDateHour( XmUbTimeBoxWidget tbox, 482 int hours ); 483 484 static void 485 AddDateMonth( XmUbTimeBoxWidget tbox, 486 int months, 487 int sub_days ); 488 489 static void 490 AddDateWeek( XmUbTimeBoxWidget tbox, 491 int weeks, 492 int sub_days ); 493 494 static void 495 CallDialogPopupCallback( XmUbTimeBoxWidget tbox, 496 Widget child, 497 int reason ); 498 499 /* If not in the child list, returns XmUbTB_CHILD_ERROR. */ 500 static int 501 ChildIndex( XmUbTimeBoxWidget tbox, 502 Widget child ); 503 504 static TIM_TIME_REF 505 CombineDateAndTime( TIM_TIME_REF date, 506 TIM_TIME_REF time ); 507 508 /* User must free returned string. */ 509 static char 510 *CompleteDateString( XmUbTimeBoxWidget tbox, 511 char *str ); 512 513 static XmUbTimeBoxStatus 514 CompleteEndDate( XmUbTimeBoxWidget tbox ); 515 516 /* True means time field has been updated. */ 517 static Boolean 518 CompleteEndDateKeyword( XmUbTimeBoxWidget tbox, 519 char *str ); 520 521 static XmUbTimeBoxStatus 522 CompleteEndTime( XmUbTimeBoxWidget tbox ); 523 524 /* True means time field has been updated. */ 525 static Boolean 526 CompleteEndTimeKeyword( XmUbTimeBoxWidget tbox, 527 char *str ); 528 529 static XmUbTimeBoxStatus 530 CompleteStartDate( XmUbTimeBoxWidget tbox ); 531 532 static XmUbTimeBoxStatus 533 CompleteStartTime( XmUbTimeBoxWidget tbox ); 534 535 static char 536 *CompleteTimeString( XmUbTimeBoxWidget tbox, 537 char *str ); 538 539 static void 540 ConvertToDateString( XmUbTimeBoxWidget tbox, 541 time_t time, 542 char *buffer, 543 int buf_len ); 544 545 static void 546 ConvertToMenuPosition( XrmValue *args, 547 Cardinal *num_args, 548 XrmValue *from, 549 XrmValue *to ); 550 551 static void 552 ConvertToTimeString( XmUbTimeBoxWidget tbox, 553 time_t time, 554 char *buffer, 555 int buf_len ); 556 557 static void 558 ConvertToWidgetFormat( XrmValue *args, 559 Cardinal *num_args, 560 XrmValue *from, 561 XrmValue *to ); 562 563 static void 564 CreateInternalWidgets( XmUbTimeBoxWidget tbox ); 565 566 static Widget 567 CreateDateField( XmUbTimeBoxWidget tbox, 568 char *name ); 569 570 static void 571 CreateDateSelectionPopup( XmUbTimeBoxWidget tbox ); 572 573 static void 574 CreateMenu( XmUbTimeBoxWidget tbox, 575 String base_name ); 576 577 static void 578 CreateMenuItems( XmUbTimeBoxWidget tbox, 579 Widget parent, 580 XmUbMenuItemRef items, 581 int num_items ); 582 583 static Widget 584 CreateTimeField( XmUbTimeBoxWidget tbox, 585 char *name ); 586 587 static void 588 CreateTimeSelectionPopup( XmUbTimeBoxWidget tbox ); 589 590 static void 591 DateCompletionCB( Widget tw, 592 XmUbTimeBoxWidget tbox, 593 XmTextVerifyCallbackStruct *call_data ); 594 595 #if XmVersion > 1001 596 static void 597 DateDropCB( Widget w, 598 XtPointer client_data, 599 XmDropProcCallbackStruct *call_data ); 600 #endif 601 602 static void 603 DateSelectedInDialogCB( Widget md, 604 XmUbTimeBoxWidget tbox, 605 XmUbMonthDisplayCallbackStruct *call_data ); 606 607 static void 608 FillInStartOfMonth( XmUbTimeBoxWidget tbox ); 609 610 static void 611 FillInStartOfWeek( XmUbTimeBoxWidget tbox ); 612 613 /* Fills in the width and height fields in the kids dimension recs. */ 614 static void 615 GetChildPrefSizes( XmUbTimeBoxWidget tbox, 616 Widget initiator, 617 XtWidgetGeometry *request, 618 KidDimensionRec sizes[] ); 619 620 XmUbTimeBoxStatus 621 GetChildString( XmUbTimeBoxWidget tbox, 622 int child, 623 char **str ); 624 625 XmUbTimeBoxStatus 626 GetStartDateTime( XmUbTimeBoxWidget tbox, 627 Boolean use_defaults, 628 TIM_TIME_REF *date_time ); 629 630 static void 631 InitializeItem( int index, 632 XmUbMenuItem items[], 633 XmUbItem item, 634 String label, 635 XtCallbackProc proc, 636 XtPointer client_data ); 637 638 static void 639 InitializeDefaultMenu( XmUbTimeBoxWidget tbox, 640 XmUbMenuItem items[], 641 int *num_items_created ); 642 643 /* The sizes array must have been processed by GetChildPrefSizes and 644 PrepareLayout before DoLayout is called. */ 645 static void 646 DoLayout( XmUbTimeBoxWidget tbox, 647 Widget initiator, 648 XtWidgetGeometry *request, 649 KidDimensionRec sizes[] ); 650 651 static void 652 KidsPreferredGeometry( Widget kid, 653 Widget initiator, 654 XtWidgetGeometry *request, 655 XtWidgetGeometry *desired ); 656 657 static void 658 MenuItemActivatedCB( Widget pb, 659 XtCallbackProc action, 660 XmAnyCallbackStruct *call_data ); 661 662 Widget 663 MonthDisplayId( XmUbTimeBoxWidget tbox ); 664 665 static void 666 PopdownDateSelectionDialogCB( Widget md, 667 XmUbTimeBoxWidget tbox, 668 XmAnyCallbackStruct *call_data ); 669 670 static void 671 PopdownTimeSelectionDialogCB( Widget tw, 672 XmUbTimeBoxWidget tbox, 673 XmAnyCallbackStruct *call_data ); 674 675 static void 676 PopupDateSelectionAction( Widget w, 677 XEvent *event, 678 String *params, 679 Cardinal num_params ); 680 681 static void 682 PopupTimeSelectionAction( Widget w, 683 XEvent *event, 684 String *params, 685 Cardinal num_params ); 686 687 /* Fills in the x and y fields in the kids dimension recs. */ 688 /* The width and height fields must be set beforehand. */ 689 static void 690 PrepareLayout( XmUbTimeBoxWidget tbox, 691 KidDimensionRec sizes[], 692 Dimension *own_width, 693 Dimension *own_height ); 694 695 /* ResizeIfNeeded fills in the sizes array. Does not have to be initialized. */ 696 static Boolean 697 ResizeIfNeeded( XmUbTimeBoxWidget tbox, 698 KidDimensionRec sizes[] ); 699 700 static void 701 SelectAllTextCB( Widget tw, 702 XmUbTimeBoxWidget tbox, 703 XmAnyCallbackStruct *call_data ); 704 705 XmUbTimeBoxStatus 706 SetChildString( XmUbTimeBoxWidget tbox, 707 int child, 708 char *str ); 709 710 static void 711 TimeCompletionCB( Widget tw, 712 XmUbTimeBoxWidget tbox, 713 XmTextVerifyCallbackStruct *call_data ); 714 715 /* If TimeCompletionFailed returns True, the problem has been repaired and 716 the calling callback should restart, otherwise it should return. */ 717 static Boolean 718 TimeCompletionCallback( Widget tw, 719 int child_index, 720 XmUbTimeBoxWidget tbox, 721 XmAnyCallbackStruct *call_data, 722 XmUbTimeBoxStatus reason ); 723 724 static void 725 TimeSelectedInDialogCB( Widget tw, 726 XmUbTimeBoxWidget tbox, 727 XmAnyCallbackStruct *call_data ); 728 729 #if XmVersion > 1001 730 static void 731 TransferDateField( Widget w, 732 XtPointer closure, 733 Atom *seltype, 734 Atom *type, 735 XtPointer value, 736 unsigned long *length, 737 int format ); 738 #endif 739 740 Widget 741 TimeSliderId( XmUbTimeBoxWidget tbox ); 742 743 static void 744 ValueChangedCB( Widget tw, 745 XmUbTimeBoxWidget tbox, 746 XmAnyCallbackStruct *call_data ); 747 748 static void 749 WarningNoResourceChange( XmUbTimeBoxWidget tbox, 750 String resource ); 751 752 /*---------------------------------------------------------------------------- 753 -- The action definitions need the declared functions. 754 ----------------------------------------------------------------------------*/ 755 756 /* Time field widget translation list. */ 757 static char timeTextTranslationTable[] = 758 "<Btn1Up>(2): popup-time-selection() \n\ 759 <Btn1Down>: grab-focus()"; 760 761 /* Date field widget translation list. */ 762 static char dateTextTranslationTable[] = 763 "<Btn1Up>(2): popup-date-selection() \n\ 764 <Btn1Down>: grab-focus()"; 765 766 static XtTranslations dateTextTranslations; 767 static XtTranslations timeTextTranslations; 768 769 /* Action list. */ 770 static XtActionsRec actionsList[] = 771 { 772 { "popup-time-selection", (XtActionProc) PopupTimeSelectionAction }, 773 { "popup-date-selection", (XtActionProc) PopupDateSelectionAction }, 774 }; 775 776 777 /*---------------------------------------------------------------------------- 778 -- Initialization of the class record. 779 ----------------------------------------------------------------------------*/ 780 781 /* This initialization has to be done after the methods have been declared. */ 782 XmUbTimeBoxClassRec xmUbTimeBoxClassRec = { 783 784 { /* Core class fields. */ 785 /* superclass */ (WidgetClass) &xmManagerClassRec, 786 /* class_name */ "XmUbTimeBox", 787 /* widget_size */ sizeof( XmUbTimeBoxRec ), 788 /* class_initialize */ ClassInitialize, 789 /* class_part_initialize */ NULL, 790 /* class_inited */ False, 791 /* initialize */ Initialize, 792 /* initialize_hook */ NULL, 793 /* realize */ XtInheritRealize, 794 /* actions */ actionsList, 795 /* num_actions */ XtNumber( actionsList ), 796 /* resources */ resources, 797 /* num_resources */ XtNumber( resources ), 798 /* xrm_class */ NULLQUARK, 799 /* compress_motion */ True, 800 /* compress_exposure */ True, 801 /* compress_enterleave */ True, 802 /* visible_interest */ False, 803 /* destroy */ Destroy, 804 /* resize */ Resize, 805 /* expose */ NULL, 806 /* set_values */ SetValues, 807 /* set_values_hook */ NULL, 808 /* set_values_almost */ XtInheritSetValuesAlmost, 809 /* get_values_hook */ GetValuesHook, 810 /* accept_focus */ NULL, 811 /* version */ XtVersion, 812 /* callback_private */ NULL, 813 /* tm_table */ NULL, 814 /* query_geometry */ QueryGeometry, 815 /* display_accelerator */ XtInheritDisplayAccelerator, 816 /* extension */ NULL 817 }, 818 { /* Composite class part. */ 819 /* geometry_manager */ GeometryManager, 820 /* change_managed */ ChangeManaged, 821 /* insert_child */ InsertChild, 822 /* delete_child */ DeleteChild, 823 /* extension */ NULL 824 }, 825 { /* Constraint class fields. */ 826 /* subresources */ NULL, 827 /* subresource_count */ 0, 828 /* constraint_size */ sizeof( XmUbTimeBoxConstraintsRec ), 829 /* initialize */ NULL, 830 /* destroy */ NULL, 831 /* set_values */ NULL, 832 /* extension */ NULL 833 }, 834 { /* XmManager class part. */ 835 /* translations */ NULL, 836 /* get_resources */ NULL, 837 /* num_get_resources */ 0, 838 /* get_constraint_resources */ NULL, 839 /* num_get_constraint_resources */ 0, 840 /* extension */ NULL 841 }, 842 { /* Time box class part. */ 843 /* popup_time_selection */ PopupTimeSelection, 844 /* popup_date_selection */ PopupDateSelection, 845 /* extension */ NULL 846 }, 847 848 }; 849 850 851 852 /* Class record pointer. */ 853 WidgetClass 854 xmUbTimeBoxWidgetClass = (WidgetClass) &xmUbTimeBoxClassRec; 855 856 857 858 /*---------------------------------------------------------------------------- 859 -- Functions 860 ----------------------------------------------------------------------------*/ 861 862 static void ActivateCB(Widget tw,XmUbTimeBoxWidget tbox,XmAnyCallbackStruct * call_data)863 ActivateCB( Widget tw, 864 XmUbTimeBoxWidget tbox, 865 XmAnyCallbackStruct *call_data ) 866 { 867 /* Variables. */ 868 XmUbTimeBoxCallbackStruct cb; 869 870 /* Code. */ 871 872 if( tbox -> tbox.activate_callback == NULL ) 873 return; 874 875 /* Set up callback structure. */ 876 877 cb.reason = XmCR_ACTIVATE; 878 cb.event = call_data -> event; 879 cb.child_index = ChildIndex( tbox, tw ); 880 cb.child = tw; 881 882 XtCallCallbackList( (Widget) tbox, tbox -> tbox.activate_callback, 883 (XtPointer) &cb ); 884 885 886 return; 887 888 } /* ActivateCB */ 889 890 891 /*----------------------------------------------------------------------*/ 892 893 static void AddDateHour(XmUbTimeBoxWidget tbox,int hours)894 AddDateHour( XmUbTimeBoxWidget tbox, 895 int hours ) 896 { 897 /* Variables. */ 898 TIM_TIME_REF curr_time; 899 900 /* Code. */ 901 902 /* Get start time. */ 903 /* Must get OK back since we defaults are enabled. */ 904 (void) GetStartDateTime( tbox, True, &curr_time ); 905 906 /* Add the specified number of hours. */ 907 TimAddHours( &curr_time, hours ); 908 909 /* Format the time and display it. */ 910 (void) XmUbTimeBoxSetEndDate( (Widget) tbox, curr_time ); 911 (void) XmUbTimeBoxSetEndTime( (Widget) tbox, curr_time ); 912 913 914 return; 915 916 } /* AddDateHour */ 917 918 919 /*----------------------------------------------------------------------*/ 920 921 static void AddDateMonth(XmUbTimeBoxWidget tbox,int months,int sub_days)922 AddDateMonth( XmUbTimeBoxWidget tbox, 923 int months, 924 int sub_days ) 925 { 926 /* Variables. */ 927 TIM_TIME_REF curr_time; 928 929 /* Code. */ 930 931 /* Get start time. */ 932 /* Must get OK back since we defaults are enabled. */ 933 (void) GetStartDateTime( tbox, True, &curr_time ); 934 935 /* Add the specified number of weeks. */ 936 TimAddMonths( &curr_time, months ); 937 938 /* Subtract days if specified. */ 939 if( sub_days > 0 ) 940 TimAddDays( &curr_time, - ( sub_days ) ); 941 942 /* Format the time and display it. */ 943 (void) XmUbTimeBoxSetEndDate( (Widget) tbox, curr_time ); 944 (void) XmUbTimeBoxSetEndTime( (Widget) tbox, curr_time ); 945 946 947 return; 948 949 } /* AddDateMonth */ 950 951 952 /*----------------------------------------------------------------------*/ 953 954 static void AddDateWeek(XmUbTimeBoxWidget tbox,int weeks,int sub_days)955 AddDateWeek( XmUbTimeBoxWidget tbox, 956 int weeks, 957 int sub_days ) 958 { 959 /* Variables. */ 960 TIM_TIME_REF curr_time; 961 962 /* Code. */ 963 964 /* Get start time. */ 965 /* Must get OK back since we defaults are enabled. */ 966 (void) GetStartDateTime( tbox, True, &curr_time ); 967 968 /* Add the specified number of weeks. */ 969 TimAddDays( &curr_time, ( 7 * weeks - sub_days ) ); 970 971 /* Format the time and display it. */ 972 (void) XmUbTimeBoxSetEndDate( (Widget) tbox, curr_time ); 973 (void) XmUbTimeBoxSetEndTime( (Widget) tbox, curr_time ); 974 975 976 return; 977 978 } /* AddDateWeek */ 979 980 981 /*----------------------------------------------------------------------*/ 982 983 static void CallDialogPopupCallback(XmUbTimeBoxWidget tbox,Widget child,int reason)984 CallDialogPopupCallback( XmUbTimeBoxWidget tbox, 985 Widget child, 986 int reason ) 987 { 988 /* Variables. */ 989 XmUbTimeBoxCallbackStruct cb; 990 991 /* Code. */ 992 993 if( tbox -> tbox.popup_selection_callback == NULL ) 994 return; 995 996 /* Set up callback structure. */ 997 998 cb.reason = reason; 999 cb.event = NULL; 1000 cb.child_index = ChildIndex( tbox, child ); 1001 cb.child = child; 1002 1003 XtCallCallbackList( (Widget) tbox, 1004 tbox -> tbox.popup_selection_callback, 1005 (XtPointer) &cb ); 1006 1007 1008 return; 1009 1010 } /* CallDialogPopupCallback */ 1011 1012 1013 /*----------------------------------------------------------------------*/ 1014 1015 static void ChangeManaged(Widget widget)1016 ChangeManaged( Widget widget ) 1017 { 1018 /* Variables. */ 1019 Boolean layout_done; 1020 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 1021 XmUbTimeBoxWidget tbox; 1022 1023 1024 /* Code. */ 1025 1026 tbox = (XmUbTimeBoxWidget) widget; 1027 1028 /* ResizeIfNeeded checks the size of all children and resizes the widget. */ 1029 layout_done = ResizeIfNeeded( tbox, kids_sizes ); 1030 1031 /* Do the layout. */ 1032 if( !layout_done ) 1033 DoLayout( tbox, NULL, NULL, kids_sizes ); 1034 1035 1036 return; 1037 1038 } /* ChangeManaged */ 1039 1040 1041 /*----------------------------------------------------------------------*/ 1042 1043 static int ChildIndex(XmUbTimeBoxWidget tbox,Widget child)1044 ChildIndex( XmUbTimeBoxWidget tbox, 1045 Widget child ) 1046 { 1047 /* Variables. */ 1048 int index; 1049 1050 /* Code. */ 1051 1052 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ){ 1053 1054 if( tbox -> tbox.internal_children[ index ] == child ) 1055 return index; 1056 1057 } /* for */ 1058 1059 1060 /* Specified child not found. */ 1061 return XmUbTB_CHILD_ERROR; 1062 1063 } /* ChildIndex */ 1064 1065 1066 /*----------------------------------------------------------------------*/ 1067 1068 static void ClassInitialize()1069 ClassInitialize() 1070 { 1071 1072 /* Variables. */ 1073 1074 /* Code. */ 1075 1076 /* Register type converters. */ 1077 XtAddConverter( XmRString, XmRwidgetFormatType, 1078 ConvertToWidgetFormat, NULL, 0 ); 1079 XtAddConverter( XmRString, XmRmenuPositionType, 1080 ConvertToMenuPosition, NULL, 0 ); 1081 1082 1083 /* Initialize class-wide flag. */ 1084 context_dependent_done = False; 1085 1086 /* Parse translations tables. */ 1087 dateTextTranslations = XtParseTranslationTable( 1088 (String) dateTextTranslationTable ); 1089 timeTextTranslations = XtParseTranslationTable( 1090 (String) timeTextTranslationTable ); 1091 1092 1093 return; 1094 1095 } /* ClassInitialize */ 1096 1097 1098 /*----------------------------------------------------------------------*/ 1099 1100 static TIM_TIME_REF CombineDateAndTime(TIM_TIME_REF date,TIM_TIME_REF time)1101 CombineDateAndTime( TIM_TIME_REF date, 1102 TIM_TIME_REF time ) 1103 { 1104 /* Variables. */ 1105 TIM_TIME_REF combined_time; 1106 1107 /* Code. */ 1108 1109 combined_time = TimMakeTime( TimIndexOfYear( date ), 1110 TimIndexOfMonth( date ), 1111 TimIndexOfDay( date ), 1112 TimHour( time ), 1113 TimMinute( time ), 1114 TimSecond( time ) ); 1115 1116 return( combined_time ); 1117 1118 } /* CombineDateAndTime */ 1119 1120 1121 /*----------------------------------------------------------------------*/ 1122 1123 static char CompleteDateString(XmUbTimeBoxWidget tbox,char * str)1124 *CompleteDateString( XmUbTimeBoxWidget tbox, 1125 char *str ) 1126 { 1127 /* Variables. */ 1128 char buffer[ TIME_STRING_BUFFER_LEN ]; 1129 TIM_TIME_REF conv_time; 1130 char *return_str; 1131 TIM_STATUS_TYPE status; 1132 1133 /* Code. */ 1134 1135 /* For empty string, we have no completion. */ 1136 if( ( str == NULL ) || ( strlen( str ) == 0 ) ) 1137 return( NULL ); 1138 1139 /* Initialize. */ 1140 buffer[ 0 ] = '\0'; 1141 1142 /* Try to parse the string with time completion. */ 1143 status = TimMakeDateFromString( &conv_time, str ); 1144 1145 if( status != TIM_OK ) 1146 return( NULL ); 1147 1148 /* Convert the time back to a string. */ 1149 ConvertToDateString( tbox, conv_time, buffer, TIME_STRING_BUFFER_LEN - 1 ); 1150 1151 if( strlen( buffer ) == 0 ) 1152 return( NULL ); 1153 1154 return_str = XtMalloc( strlen( buffer ) + 1 ); 1155 strcpy( return_str, buffer ); 1156 1157 1158 return( return_str ); 1159 1160 } /* CompleteDateString */ 1161 1162 1163 /*----------------------------------------------------------------------*/ 1164 1165 static XmUbTimeBoxStatus CompleteEndDate(XmUbTimeBoxWidget tbox)1166 CompleteEndDate( XmUbTimeBoxWidget tbox ) 1167 { 1168 /* Variables. */ 1169 char *completed_str; 1170 Boolean done; 1171 XmUbTimeBoxStatus status; 1172 char *str; 1173 1174 /* Code. */ 1175 1176 /* Extract the date string. */ 1177 status = XmUbTimeBoxGetEndDateString( (Widget) tbox, &str ); 1178 if( status != TBOX_OK ) 1179 return( status ); 1180 1181 /* Try to complete as keyword. */ 1182 done = CompleteEndDateKeyword( tbox, str ); 1183 if( !done ){ 1184 1185 /* If not successful, try numeric completion. */ 1186 completed_str = CompleteDateString( tbox, str ); 1187 1188 if( completed_str == NULL ) 1189 status = TBOX_NO_COMPLETION; 1190 1191 else { 1192 status = XmUbTimeBoxSetEndDateString( (Widget) tbox, completed_str ); 1193 XtFree( completed_str ); 1194 } 1195 1196 } 1197 1198 /* Cleanup. */ 1199 if( str != NULL ) 1200 XtFree( str ); 1201 1202 1203 return( status ); 1204 1205 } /* CompleteEndDate */ 1206 1207 1208 /*----------------------------------------------------------------------*/ 1209 1210 static Boolean CompleteEndDateKeyword(XmUbTimeBoxWidget tbox,char * str)1211 CompleteEndDateKeyword( XmUbTimeBoxWidget tbox, 1212 char *str ) 1213 { 1214 #define COMPLETE_END_DATE_NOOP 0 1215 #define COMPLETE_END_DATE_ADD_WEEKS 1 1216 #define COMPLETE_END_DATE_ADD_MONTHS 2 1217 #define COMPLETE_END_DATE_ADD_DAYS 3 1218 #define COMPLETE_END_DATE_ADD_YEARS 4 1219 1220 /* Variables. */ 1221 TIM_TIME_REF conv_time; 1222 int days, months, weeks, years; 1223 char keyword[ 20 ]; 1224 int matches; 1225 char pattern[ MAX_PATTERN_LENGTH ]; 1226 int operation = COMPLETE_END_DATE_NOOP; 1227 XmUbTimeBoxStatus status; 1228 1229 /* Code. */ 1230 1231 /* For empty string, we have no completion. */ 1232 if( ( str == NULL ) || ( strlen( str ) == 0 ) ) 1233 return( False ); 1234 1235 /* Try different completion schemes. */ 1236 sprintf( pattern, "+%s[%s]", "%d%", tbox -> tbox.week_marker ); 1237 matches = sscanf( str, pattern, &weeks, keyword ); 1238 if( matches == 2 ){ 1239 1240 if( weeks < 0 ) 1241 return( False ); 1242 1243 operation = COMPLETE_END_DATE_ADD_WEEKS; 1244 } 1245 1246 if( operation == COMPLETE_END_DATE_NOOP ){ 1247 sprintf( pattern, "+%s[%s]", "%d%", tbox -> tbox.month_marker ); 1248 matches = sscanf( str, pattern, &months, keyword ); 1249 if( matches == 2 ){ 1250 1251 if( months < 0 ) 1252 return( False ); 1253 1254 operation = COMPLETE_END_DATE_ADD_MONTHS; 1255 } 1256 } 1257 1258 if( operation == COMPLETE_END_DATE_NOOP ){ 1259 sprintf( pattern, "+%s[%s]", "%d%", tbox -> tbox.day_marker ); 1260 matches = sscanf( str, pattern, &days, keyword ); 1261 if( matches == 2 ){ 1262 1263 if( days < 0 ) 1264 return( False ); 1265 1266 operation = COMPLETE_END_DATE_ADD_DAYS; 1267 } 1268 } 1269 1270 if( operation == COMPLETE_END_DATE_NOOP ){ 1271 sprintf( pattern, "+%s[%s]", "%d%", tbox -> tbox.year_marker ); 1272 matches = sscanf( str, pattern, &years, keyword ); 1273 if( matches == 2 ){ 1274 1275 if( days < 0 ) 1276 return( False ); 1277 1278 operation = COMPLETE_END_DATE_ADD_YEARS; 1279 } 1280 } 1281 1282 /* No keyword means add days. */ 1283 if( operation == COMPLETE_END_DATE_NOOP ){ 1284 matches = sscanf( str, "+%d", &days ); 1285 if( matches == 1 ){ 1286 1287 if( days < 0 ) 1288 return( False ); 1289 1290 operation = COMPLETE_END_DATE_ADD_DAYS; 1291 } 1292 } 1293 1294 if( operation == COMPLETE_END_DATE_NOOP ) 1295 return( False ); 1296 1297 1298 /* We must have a date to start from. */ 1299 status = XmUbTimeBoxGetStartDate( (Widget) tbox, &conv_time ); 1300 if( status != TBOX_OK ) 1301 return( False ); 1302 1303 /* We have a valid start date. Complete the desired operation. */ 1304 switch( operation ){ 1305 1306 case COMPLETE_END_DATE_ADD_WEEKS: 1307 TimAddDays( &conv_time, 7 * weeks ); 1308 break; 1309 1310 case COMPLETE_END_DATE_ADD_MONTHS: 1311 TimAddMonths( &conv_time, months ); 1312 break; 1313 1314 case COMPLETE_END_DATE_ADD_DAYS: 1315 TimAddDays( &conv_time, days ); 1316 break; 1317 1318 case COMPLETE_END_DATE_ADD_YEARS: 1319 TimAddYears( &conv_time, years ); 1320 break; 1321 1322 default: 1323 return( False ); 1324 } 1325 1326 1327 /* Set the new time, both date and time. */ 1328 (void) XmUbTimeBoxSetEndDate( (Widget) tbox, conv_time ); 1329 (void) XmUbTimeBoxSetEndTime( (Widget) tbox, conv_time ); 1330 1331 1332 return( True ); 1333 1334 #undef COMPLETE_END_DATE_NOOP 1335 #undef COMPLETE_END_DATE_ADD_WEEKS 1336 #undef COMPLETE_END_DATE_ADD_MONTHS 1337 #undef COMPLETE_END_DATE_ADD_DAYS 1338 #undef COMPLETE_END_DATE_ADD_YEARS 1339 } /* CompleteEndDateKeyword */ 1340 1341 1342 /*----------------------------------------------------------------------*/ 1343 1344 static XmUbTimeBoxStatus CompleteEndTime(XmUbTimeBoxWidget tbox)1345 CompleteEndTime( XmUbTimeBoxWidget tbox ) 1346 { 1347 /* Variables. */ 1348 char *completed_str; 1349 Boolean done; 1350 char *str; 1351 XmUbTimeBoxStatus status; 1352 1353 /* Code. */ 1354 1355 /* Extract the time string. */ 1356 status = XmUbTimeBoxGetEndTimeString( (Widget) tbox, &str ); 1357 if( status != TBOX_OK ) 1358 return( status ); 1359 1360 /* Try to complete as keyword. */ 1361 done = CompleteEndTimeKeyword( tbox, str ); 1362 1363 if( !done ){ 1364 1365 /* If not successful, try numeric completion. */ 1366 completed_str = CompleteTimeString( tbox, str ); 1367 1368 if( completed_str == NULL ) 1369 status = TBOX_NO_COMPLETION; 1370 1371 else { 1372 status = XmUbTimeBoxSetEndTimeString( (Widget) tbox, completed_str ); 1373 XtFree( completed_str ); 1374 } 1375 1376 } 1377 1378 /* Cleanup. */ 1379 if( str != NULL ) 1380 XtFree( str ); 1381 1382 1383 return( status ); 1384 1385 } /* CompleteEndTime */ 1386 1387 1388 /*----------------------------------------------------------------------*/ 1389 1390 static Boolean CompleteEndTimeKeyword(XmUbTimeBoxWidget tbox,char * str)1391 CompleteEndTimeKeyword( XmUbTimeBoxWidget tbox, 1392 char *str ) 1393 { 1394 #define COMPLETE_END_TIME_NOOP 0 1395 #define COMPLETE_END_TIME_ADD_HOURS 1 1396 #define COMPLETE_END_TIME_ADD_MINUTES 2 1397 1398 /* Variables. */ 1399 TIM_TIME_REF conv_time; 1400 int hours, minutes; 1401 char keyword[ 20 ]; 1402 int matches; 1403 int operation = COMPLETE_END_TIME_NOOP; 1404 char pattern[ MAX_PATTERN_LENGTH ]; 1405 XmUbTimeBoxStatus status; 1406 1407 /* Code. */ 1408 1409 /* For empty string, we have no completion. */ 1410 if( ( str == NULL ) || ( strlen( str ) == 0 ) ) 1411 return( False ); 1412 1413 /* Try different completion schemes. */ 1414 sprintf( pattern, "+%s[%s]", "%d%", tbox -> tbox.hour_marker ); 1415 matches = sscanf( str, pattern, &hours, keyword ); 1416 if( matches == 2 ){ 1417 1418 if( hours < 0 ) 1419 return( False ); 1420 1421 operation = COMPLETE_END_TIME_ADD_HOURS; 1422 } 1423 1424 if( operation == COMPLETE_END_TIME_NOOP ){ 1425 sprintf( pattern, "+%s[%s]", "%d%", tbox -> tbox.minute_marker ); 1426 matches = sscanf( str, pattern, &minutes, keyword ); 1427 if( matches == 2 ){ 1428 1429 if( minutes < 0 ) 1430 return( False ); 1431 1432 operation = COMPLETE_END_TIME_ADD_MINUTES; 1433 } 1434 } 1435 1436 /* No keyword means add hours. */ 1437 if( operation == COMPLETE_END_TIME_NOOP ){ 1438 matches = sscanf( str, "+%d", &hours ); 1439 if( matches == 1 ){ 1440 1441 if( hours < 0 ) 1442 return( False ); 1443 1444 operation = COMPLETE_END_TIME_ADD_HOURS; 1445 } 1446 } 1447 1448 if( operation == COMPLETE_END_TIME_NOOP ) 1449 return( False ); 1450 1451 1452 /* We must have a time to start from. */ 1453 status = XmUbTimeBoxGetStartTime( (Widget) tbox, &conv_time ); 1454 if( status != TBOX_OK ) 1455 return( False ); 1456 1457 /* We have a valid start time. Complete the desired operation. */ 1458 switch( operation ){ 1459 1460 case COMPLETE_END_TIME_ADD_HOURS: 1461 TimAddHours( &conv_time, hours ); 1462 break; 1463 1464 case COMPLETE_END_TIME_ADD_MINUTES: 1465 TimAddMinutes( &conv_time, minutes ); 1466 break; 1467 1468 default: 1469 return( False ); 1470 } 1471 1472 /* Set the new time, both date and time. */ 1473 (void) XmUbTimeBoxSetEndTime( (Widget) tbox, conv_time ); 1474 1475 1476 return( True ); 1477 1478 #undef COMPLETE_END_TIME_NOOP 1479 #undef COMPLETE_END_TIME_ADD_HOURS 1480 #undef COMPLETE_END_TIME_ADD_MINUTES 1481 } /* CompleteEndTimeKeyword */ 1482 1483 1484 /*----------------------------------------------------------------------*/ 1485 1486 static XmUbTimeBoxStatus CompleteStartDate(XmUbTimeBoxWidget tbox)1487 CompleteStartDate( XmUbTimeBoxWidget tbox ) 1488 { 1489 /* Variables. */ 1490 char *completed_str; 1491 XmUbTimeBoxStatus status; 1492 char *str; 1493 1494 /* Code. */ 1495 1496 /* Extract the date string. */ 1497 status = XmUbTimeBoxGetStartDateString( (Widget) tbox, &str ); 1498 if( status != TBOX_OK ) 1499 return( status ); 1500 1501 completed_str = CompleteDateString( tbox, str ); 1502 1503 if( completed_str == NULL ) 1504 status = TBOX_NO_COMPLETION; 1505 1506 else { 1507 status = XmUbTimeBoxSetStartDateString( (Widget) tbox, completed_str ); 1508 XtFree( completed_str ); 1509 } 1510 1511 /* Cleanup. */ 1512 if( str != NULL ) 1513 XtFree( str ); 1514 1515 1516 return( status ); 1517 1518 } /* CompleteStartDate */ 1519 1520 1521 /*----------------------------------------------------------------------*/ 1522 1523 static XmUbTimeBoxStatus CompleteStartTime(XmUbTimeBoxWidget tbox)1524 CompleteStartTime( XmUbTimeBoxWidget tbox ) 1525 { 1526 /* Variables. */ 1527 char *completed_str; 1528 XmUbTimeBoxStatus status; 1529 char *str; 1530 1531 /* Code. */ 1532 1533 /* Extract the time string. */ 1534 status = XmUbTimeBoxGetStartTimeString( (Widget) tbox, &str ); 1535 if( status != TBOX_OK ) 1536 return( status ); 1537 1538 completed_str = CompleteTimeString( tbox, str ); 1539 1540 if( completed_str == NULL ) 1541 status = TBOX_NO_COMPLETION; 1542 1543 else { 1544 status = XmUbTimeBoxSetStartTimeString( (Widget) tbox, completed_str ); 1545 XtFree( completed_str ); 1546 } 1547 1548 /* Cleanup. */ 1549 if( str != NULL ) 1550 XtFree( str ); 1551 1552 1553 return( status ); 1554 1555 } /* CompleteStartTime */ 1556 1557 1558 /*----------------------------------------------------------------------*/ 1559 1560 static char CompleteTimeString(XmUbTimeBoxWidget tbox,char * str)1561 *CompleteTimeString( XmUbTimeBoxWidget tbox, 1562 char *str ) 1563 { 1564 /* Variables. */ 1565 char buffer[ TIME_STRING_BUFFER_LEN ]; 1566 TIM_TIME_REF conv_time; 1567 int hours; 1568 int matches; 1569 char *return_str; 1570 TIM_STATUS_TYPE status; 1571 1572 /* Code. */ 1573 1574 /* For empty string, we have no completion. */ 1575 if( ( str == NULL ) || ( strlen( str ) == 0 ) ) 1576 return( NULL ); 1577 1578 /* Initialize. */ 1579 buffer[ 0 ] = '\0'; 1580 1581 /* Try to parse the string with time completion. */ 1582 status = TimMakeTimeFromString( &conv_time, str ); 1583 1584 if( status != TIM_OK ){ 1585 1586 /* Allow expansion of hours. Not yet in time package. */ 1587 matches = sscanf( str, "%d", &hours ); 1588 if( matches == 1 ) 1589 conv_time = TimMakeTime( TIM_NOW, TIM_NOW, TIM_NOW, hours, 0, 0 ); 1590 else 1591 return( NULL ); 1592 } 1593 1594 /* Convert the time back to a string. */ 1595 ConvertToTimeString( tbox, conv_time, buffer, TIME_STRING_BUFFER_LEN - 1 ); 1596 1597 if( strlen( buffer ) == 0 ) 1598 return( NULL ); 1599 1600 return_str = XtMalloc( strlen( buffer ) + 1 ); 1601 strcpy( return_str, buffer ); 1602 1603 1604 return( return_str ); 1605 1606 } /* CompleteTimeString */ 1607 1608 1609 /*----------------------------------------------------------------------*/ 1610 1611 static void ConvertToDateString(XmUbTimeBoxWidget tbox,time_t time,char * buffer,int buf_len)1612 ConvertToDateString( XmUbTimeBoxWidget tbox, 1613 time_t time, 1614 char *buffer, 1615 int buf_len ) 1616 { 1617 1618 /* Code. */ 1619 1620 TimFormatDate( time, buffer, buf_len ); 1621 1622 1623 return; 1624 1625 } /* ConvertToDateString */ 1626 1627 1628 /*----------------------------------------------------------------------*/ 1629 1630 static void ConvertToMenuPosition(XrmValue * args,Cardinal * num_args,XrmValue * from,XrmValue * to)1631 ConvertToMenuPosition( XrmValue *args, 1632 Cardinal *num_args, 1633 XrmValue *from, 1634 XrmValue *to ) 1635 { 1636 1637 /* Variables. */ 1638 static menuPositionType conv_menu_position; 1639 1640 1641 /* Code. */ 1642 1643 if( *num_args != 0 ) 1644 XtWarningMsg( "wrongParameters", "ConvertToMenuPosition", 1645 "XtToolkitError", "Conversion needs no extra arguments", 1646 (String *) NULL, (Cardinal *) NULL ); 1647 1648 if( strcmp( (char *) from -> addr, "POSITION_FIRST" ) == 0 ) 1649 conv_menu_position = XmUbPOSITION_FIRST; 1650 1651 else if( strcmp( (char *) from -> addr, "POSITION_LAST" ) == 0 ) 1652 conv_menu_position = XmUbPOSITION_LAST; 1653 1654 else { 1655 XtWarningMsg( "wrongParameters", "ConvertToMenuPosition", 1656 "XtToolkitError", "Cannot convert to type menuPositionType", 1657 (String *) NULL, (Cardinal *) 0 ); 1658 conv_menu_position = XmUbPOSITION_FIRST; 1659 } 1660 1661 ( *to ).size = sizeof( menuPositionType ); 1662 ( *to ).addr = (XtPointer) &conv_menu_position; 1663 1664 1665 return; 1666 1667 } /* ConvertToMenuPosition */ 1668 1669 1670 /*----------------------------------------------------------------------*/ 1671 1672 static void ConvertToTimeString(XmUbTimeBoxWidget tbox,time_t time,char * buffer,int buf_len)1673 ConvertToTimeString( XmUbTimeBoxWidget tbox, 1674 time_t time, 1675 char *buffer, 1676 int buf_len ) 1677 { 1678 1679 /* Code. */ 1680 1681 TimFormatTime( time, buffer, buf_len ); 1682 1683 1684 return; 1685 1686 } /* ConvertToTimeString */ 1687 1688 1689 /*----------------------------------------------------------------------*/ 1690 1691 static void ConvertToWidgetFormat(XrmValue * args,Cardinal * num_args,XrmValue * from,XrmValue * to)1692 ConvertToWidgetFormat( XrmValue *args, 1693 Cardinal *num_args, 1694 XrmValue *from, 1695 XrmValue *to ) 1696 { 1697 1698 /* Variables. */ 1699 static widgetFormatType conv_widget_format; 1700 1701 1702 /* Code. */ 1703 1704 if( *num_args != 0 ) 1705 XtWarningMsg( "wrongParameters", "ConvertToWidgetFormat", 1706 "XtToolkitError", "Conversion needs no extra arguments", 1707 (String *) NULL, (Cardinal *) NULL ); 1708 1709 if( strcmp( (char *) from -> addr, "TB_FORMAT_D" ) == 0 ) 1710 conv_widget_format = XmUbTB_FORMAT_D; 1711 1712 else if( strcmp( (char *) from -> addr, "TB_FORMAT_T" ) == 0 ) 1713 conv_widget_format = XmUbTB_FORMAT_T; 1714 1715 else if( strcmp( (char *) from -> addr, "TB_FORMAT_DT" ) == 0 ) 1716 conv_widget_format = XmUbTB_FORMAT_DT; 1717 1718 else if( strcmp( (char *) from -> addr, "TB_FORMAT_DD" ) == 0 ) 1719 conv_widget_format = XmUbTB_FORMAT_DD; 1720 1721 else if( strcmp( (char *) from -> addr, "TB_FORMAT_DTDT" ) == 0 ) 1722 conv_widget_format = XmUbTB_FORMAT_DTDT; 1723 1724 else if( strcmp( (char *) from -> addr, "TB_FORMAT_DTT" ) == 0 ) 1725 conv_widget_format = XmUbTB_FORMAT_DTT; 1726 1727 else if( strcmp( (char *) from -> addr, "TB_FORMAT_TT" ) == 0 ) 1728 conv_widget_format = XmUbTB_FORMAT_TT; 1729 1730 1731 else { 1732 XtWarningMsg( "wrongParameters", "ConvertToWidgetFormat", 1733 "XtToolkitError", "Cannot convert to type widgetFormatType", 1734 (String *) NULL, (Cardinal *) 0 ); 1735 conv_widget_format = XmUbTB_FORMAT_DTDT; 1736 } 1737 1738 ( *to ).size = sizeof( widgetFormatType ); 1739 ( *to ).addr = (XtPointer) &conv_widget_format; 1740 1741 1742 return; 1743 1744 } /* ConvertToWidgetFormat */ 1745 1746 1747 /*----------------------------------------------------------------------*/ 1748 1749 static void CreateInternalWidgets(XmUbTimeBoxWidget tbox)1750 CreateInternalWidgets( XmUbTimeBoxWidget tbox ) 1751 { 1752 1753 /* Variables. */ 1754 char *name; 1755 String wname; 1756 1757 /* Code. */ 1758 1759 /* Get the name of the "parent" widget. */ 1760 wname = XtName( (Widget)tbox ); 1761 1762 name = XtMalloc( strlen( wname ) + 3 ); 1763 1764 /* Create the menu. */ 1765 if( tbox -> tbox.menu_enabled ) 1766 CreateMenu( tbox, wname ); 1767 1768 /* First date field. */ 1769 if( ( tbox -> tbox.widget_format == XmUbTB_FORMAT_D ) || 1770 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DT ) || 1771 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DD ) || 1772 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTDT ) || 1773 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTT ) ){ 1774 1775 sprintf( name, "%sFd", wname ); 1776 1777 tbox -> tbox.internal_children[ XmUbTB_CHILD_START_DATE ] = 1778 CreateDateField( tbox, name ); 1779 1780 XtManageChild( tbox -> tbox.internal_children[ XmUbTB_CHILD_START_DATE ] ); 1781 } 1782 1783 /* First time field. */ 1784 if( ( tbox -> tbox.widget_format == XmUbTB_FORMAT_T ) || 1785 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DT ) || 1786 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_TT ) || 1787 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTDT ) || 1788 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTT ) ){ 1789 1790 sprintf( name, "%sFt", wname ); 1791 1792 tbox -> tbox.internal_children[ XmUbTB_CHILD_START_TIME ] = 1793 CreateTimeField( tbox, name ); 1794 1795 XtManageChild( tbox -> tbox.internal_children[ XmUbTB_CHILD_START_TIME ] ); 1796 } 1797 1798 1799 /* Second date field. */ 1800 if( ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DD ) || 1801 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTDT ) ) { 1802 1803 sprintf( name, "%sSd", wname ); 1804 1805 tbox -> tbox.internal_children[ XmUbTB_CHILD_END_DATE ] = 1806 CreateDateField( tbox, name ); 1807 1808 XtManageChild( tbox -> tbox.internal_children[ XmUbTB_CHILD_END_DATE ] ); 1809 } 1810 1811 /* Second time field. */ 1812 if( ( tbox -> tbox.widget_format == XmUbTB_FORMAT_TT ) || 1813 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTDT ) || 1814 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTT ) ){ 1815 1816 sprintf( name, "%sSt", wname ); 1817 1818 tbox -> tbox.internal_children[ XmUbTB_CHILD_END_TIME ] = 1819 CreateTimeField( tbox, name ); 1820 1821 XtManageChild( tbox -> tbox.internal_children[ XmUbTB_CHILD_END_TIME ] ); 1822 } 1823 1824 /* Cleanup. */ 1825 XtFree( name ); 1826 1827 1828 1829 return; 1830 1831 } /* CreateInternalWidgets */ 1832 1833 1834 /*----------------------------------------------------------------------*/ 1835 1836 static Widget CreateDateField(XmUbTimeBoxWidget tbox,char * name)1837 CreateDateField( XmUbTimeBoxWidget tbox, 1838 char *name ) 1839 { 1840 1841 /* Variables. */ 1842 Arg args[ 5 ]; 1843 short columns; 1844 Atom compound_text_atom; 1845 Atom date_transfer_atom; 1846 Cardinal n; 1847 Atom targets[ 2 ]; 1848 char text_buffer[ TEXT_BUFFER_LENGTH ]; 1849 TIM_TIME_REF time; 1850 Widget w; 1851 1852 /* Code. */ 1853 1854 /* Find out how long the longest text in the time field is. */ 1855 /* Assume that Dec. 31 yields the longest text. */ 1856 time = TimMakeTime( 1970, 12, 31, 23, 59, 59 ); 1857 TimFormatDate( time, text_buffer, TEXT_BUFFER_LENGTH - 1 ); 1858 columns = (short) ( strlen( text_buffer ) + 1 ); 1859 1860 n = 0; 1861 XtSetArg( args[ n ], XmNeditMode, XmSINGLE_LINE_EDIT ); n++; 1862 XtSetArg( args[ n ], XmNcolumns, columns ); n++; 1863 XtSetArg( args[ n ], XmNtraversalOn, True ); n++; 1864 1865 w = XmCreateText( (Widget) tbox, name, args, n ); 1866 1867 /* We want to be able to pop up our own date selection dialog. */ 1868 XtOverrideTranslations( w, dateTextTranslations ); 1869 1870 /* We want the completion callback when losing focus. */ 1871 XtAddCallback( w, XmNlosingFocusCallback, 1872 (XtCallbackProc) DateCompletionCB, (XtPointer) tbox ); 1873 1874 /* Select all text when gaining focus. */ 1875 XtAddCallback( w, XmNfocusCallback, 1876 (XtCallbackProc) SelectAllTextCB, (XtPointer) tbox ); 1877 1878 XtAddCallback( w, XmNactivateCallback, 1879 (XtCallbackProc) ActivateCB, (XtPointer) tbox ); 1880 1881 XtAddCallback( w, XmNvalueChangedCallback, 1882 (XtCallbackProc) ValueChangedCB, (XtPointer) tbox ); 1883 1884 #if XmVersion > 1001 1885 /* We want to enable date transfer in drag and drop format. */ 1886 compound_text_atom = XmInternAtom( XtDisplay( w ), "COMPOUND_TEXT", False ); 1887 date_transfer_atom = XmInternAtom( XtDisplay( w ), XmUbDATE_TRANSFER, 1888 False ); 1889 1890 targets[ 0 ] = date_transfer_atom; 1891 targets[ 1 ] = compound_text_atom; 1892 1893 n = 0; 1894 XtSetArg( args[ n ], XmNimportTargets, targets ); n++; 1895 XtSetArg( args[ n ], XmNnumImportTargets, XtNumber( targets ) ); n++; 1896 XtSetArg( args[ n ], XmNdropProc, DateDropCB ); n++; 1897 1898 XmDropSiteUpdate( w, args, n ); 1899 1900 #endif 1901 1902 return( w ); 1903 1904 } /* CreateDateField */ 1905 1906 1907 /*----------------------------------------------------------------------*/ 1908 1909 static void CreateDateSelectionPopup(XmUbTimeBoxWidget tbox)1910 CreateDateSelectionPopup( XmUbTimeBoxWidget tbox ) 1911 { 1912 /* Variables. */ 1913 Arg args[ 8 ]; 1914 Widget month_display; 1915 Cardinal n; 1916 char *name_buffer; 1917 String wname; 1918 XmString xm, mxm, wxm; 1919 1920 /* Code. */ 1921 1922 /* Reset flag that stop child creation temporarily. */ 1923 tbox -> tbox.internal_widgets_created = False; 1924 1925 /* Get the name of the "parent" widget. */ 1926 wname = XtName( (Widget)tbox ); 1927 1928 name_buffer = XtMalloc( strlen( wname ) + 8 ); 1929 1930 /* The dialog itself. */ 1931 sprintf( name_buffer, "%sDtDi", wname ); 1932 /* We don't need any OK or Cancel buttons, so create a normal form dialog. */ 1933 1934 n = 0; 1935 tbox -> tbox.date_selection_popup = XmCreateFormDialog( 1936 (Widget) tbox, name_buffer, args, n ); 1937 1938 /* Set resources on the shell. */ 1939 n = 0; 1940 XtSetArg( args[ n ], XmNdeleteResponse, XmDO_NOTHING ); n++; 1941 if( tbox -> tbox.date_selection_title != NULL ){ 1942 XtSetArg( args[ n ], XmNtitle, tbox -> tbox.date_selection_title ); n++; 1943 } else { 1944 XtSetArg( args[ n ], XmNtitle, default_date_selection_title ); n++; 1945 } 1946 1947 XtSetValues( XtParent( tbox -> tbox.date_selection_popup ), args, n ); 1948 1949 /* We must catch close events on the shell and prevent it from being 1950 destroyed. */ 1951 XmAddProtocolCallback( XtParent( tbox -> tbox.date_selection_popup ), 1952 protocol_atom, delete_atom, 1953 (XtCallbackProc) PopdownDateSelectionDialogCB, 1954 (XtPointer) tbox ); 1955 1956 sprintf( name_buffer, "%sMd", wname ); 1957 n = 0; 1958 XtSetArg( args[ n ], XmNmarginHeight, 10 ); n++; 1959 XtSetArg( args[ n ], XmNmarginWidth, 5 ); n++; 1960 1961 if( tbox -> tbox.year_label == NULL ) 1962 xm = XmStringCreateLtoR( default_year_string, XmSTRING_DEFAULT_CHARSET ); 1963 else 1964 xm = tbox -> tbox.year_label; 1965 XtSetArg( args[ n ], XmUbNmdiYearLabel, xm ); n++; 1966 1967 if( tbox -> tbox.month_label == NULL ) 1968 mxm = XmStringCreateLtoR( default_month_string, XmSTRING_DEFAULT_CHARSET ); 1969 else 1970 mxm = tbox -> tbox.month_label; 1971 XtSetArg( args[ n ], XmUbNmdiMonthLabel, mxm ); n++; 1972 1973 if( tbox -> tbox.week_label == NULL ) 1974 wxm = XmStringCreateLtoR( default_week_string, XmSTRING_DEFAULT_CHARSET ); 1975 else 1976 wxm = tbox -> tbox.week_label; 1977 XtSetArg( args[ n ], XmUbNmdiWeekLabel, wxm ); n++; 1978 1979 1980 month_display = XmUbCreateMonthDisplay( 1981 tbox -> tbox.date_selection_popup, name_buffer, args, n ); 1982 1983 if( tbox -> tbox.year_label == NULL ) 1984 XmStringFree( xm ); 1985 if( tbox -> tbox.month_label == NULL ) 1986 XmStringFree( mxm ); 1987 if( tbox -> tbox.week_label == NULL ) 1988 XmStringFree( wxm ); 1989 1990 /* DateSelectedInDialogCB must also pop the dialog down. If we add both 1991 here it is not guaranteed that the dialog exists when our selection 1992 callback is called. */ 1993 XtAddCallback( month_display, XmUbNmdiDateSelectedCallback, 1994 (XtCallbackProc) DateSelectedInDialogCB, (XtPointer) tbox ); 1995 1996 n = 0; 1997 XtSetArg( args[ n ], XmNtopAttachment, XmATTACH_FORM ); n++; 1998 XtSetArg( args[ n ], XmNleftAttachment, XmATTACH_FORM ); n++; 1999 XtSetArg( args[ n ], XmNrightAttachment, XmATTACH_FORM ); n++; 2000 XtSetArg( args[ n ], XmNbottomAttachment, XmATTACH_FORM ); n++; 2001 XtSetValues( month_display, args, n ); 2002 2003 /* For own callbacks to take effect. */ 2004 XmUbMonthDisplaySetMonth( month_display, 0, 0 ); 2005 2006 XtManageChild( month_display ); 2007 2008 /* Cleanup. */ 2009 XtFree( name_buffer ); 2010 2011 /* Back to stopping child widgets. */ 2012 tbox -> tbox.internal_widgets_created = True; 2013 2014 2015 return; 2016 2017 } /* CreateDateSelectionPopup */ 2018 2019 2020 /*----------------------------------------------------------------------*/ 2021 2022 static void CreateMenu(XmUbTimeBoxWidget tbox,String base_name)2023 CreateMenu( XmUbTimeBoxWidget tbox, 2024 String base_name ) 2025 { 2026 2027 /* Variables. */ 2028 Arg args[ 8 ]; 2029 Cardinal n; 2030 char *name; 2031 2032 2033 /* Code. */ 2034 2035 /* Allocate room enough for the possible default names. */ 2036 name = XtMalloc( strlen( base_name ) + 10 ); 2037 2038 /* Must create a menu bar, since a cascade button will only accept such a 2039 parent. */ 2040 sprintf( name, "%sBr", base_name ); 2041 n = 0; 2042 XtSetArg( args[ n ], XmNmarginHeight, 0 ); n++; 2043 XtSetArg( args[ n ], XmNmarginWidth, 0 ); n++; 2044 XtSetArg( args[ n ], XmNspacing, 0 ); n++; 2045 XtSetArg( args[ n ], XmNtraversalOn, True ); n++; 2046 tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_BAR ] = 2047 XmCreateMenuBar( (Widget) tbox, name, args, n ); 2048 2049 /* Pulldown menu. */ 2050 sprintf( name, "%sPd", base_name ); 2051 n = 0; 2052 tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_PD ] = 2053 XmCreatePulldownMenu( 2054 tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_BAR ], name, args, n ); 2055 2056 /* The cascade button. */ 2057 sprintf( name, "%sCa", base_name ); 2058 n = 0; 2059 2060 if( tbox -> tbox.menu_label != NULL ){ 2061 XtSetArg( args[ n ], XmNlabelString, tbox -> tbox.menu_label ); n++; 2062 XtSetArg( args[ n ], XmNlabelType, XmSTRING ); n++; 2063 2064 } else if( tbox -> tbox.menu_pixmap != XmUNSPECIFIED_PIXMAP ){ 2065 XtSetArg( args[ n ], XmNlabelPixmap, tbox -> tbox.menu_pixmap ); n++; 2066 XtSetArg( args[ n ], XmNlabelType, XmPIXMAP ); n++; 2067 2068 } else { 2069 tbox -> tbox.menu_label = 2070 XmStringCreateLtoR( "-", XmSTRING_DEFAULT_CHARSET ); 2071 2072 XtSetArg( args[ n ], XmNlabelString, tbox -> tbox.menu_label ); n++; 2073 XtSetArg( args[ n ], XmNlabelType, XmSTRING ); n++; 2074 XtSetArg( args[ n ], XmNmarginHeight, 0 ); n++; 2075 2076 } 2077 2078 XtSetArg( args[ n ], XmNalignment, XmALIGNMENT_CENTER ); n++; 2079 XtSetArg( args[ n ], XmNsubMenuId, 2080 tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_PD ] ); n++; 2081 XtSetArg( args[ n ], XmNshadowThickness, 0 ); n++; 2082 XtSetArg( args[ n ], XmNtraversalOn, True ); n++; 2083 2084 tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_CASC ] = 2085 XmCreateCascadeButton( 2086 tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_BAR ], name, args, n ); 2087 2088 /* The menu items. */ 2089 if( tbox -> tbox.menu_items == NULL ){ 2090 2091 XmUbMenuItem default_menu_items[ MAX_NO_DEFAULT_MENU_ITEMS ]; 2092 int num_created; 2093 2094 /* Initialize the array. */ 2095 InitializeDefaultMenu( tbox, default_menu_items, &num_created ); 2096 2097 CreateMenuItems( 2098 tbox, tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_PD ], 2099 default_menu_items, num_created ); 2100 2101 } else 2102 CreateMenuItems( 2103 tbox, tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_PD ], 2104 tbox -> tbox.menu_items, tbox -> tbox.num_menu_items ); 2105 2106 2107 XtManageChild( tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_CASC ] ); 2108 XtManageChild( tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_BAR ] ); 2109 2110 XtFree( name ); 2111 2112 2113 return; 2114 2115 } /* CreateMenu */ 2116 2117 2118 /*----------------------------------------------------------------------*/ 2119 2120 static void CreateMenuItems(XmUbTimeBoxWidget tbox,Widget parent,XmUbMenuItemRef items,int num_items)2121 CreateMenuItems( XmUbTimeBoxWidget tbox, 2122 Widget parent, 2123 XmUbMenuItemRef items, 2124 int num_items ) 2125 { 2126 /* Variables. */ 2127 Arg args[ 5 ]; 2128 char *default_name; 2129 int index; 2130 Cardinal n; 2131 Widget w; 2132 2133 /* Code. */ 2134 2135 default_name = XtMalloc( strlen( XtName( parent ) ) + 3 ); 2136 sprintf( default_name, "%sMI", XtName( parent ) ); 2137 2138 for( index = 0; index < num_items; index ++ ){ 2139 2140 switch( items[ index ].item ){ 2141 case XmUbITEM_SEPARATOR: 2142 n = 0; 2143 XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL ); n++; 2144 w = XmCreateSeparator( parent, 2145 ( items[ index ].name == NULL ? default_name : items[ index ].name ), 2146 args, n ); 2147 2148 break; 2149 2150 case XmUbITEM_PUSH_BUTTON: 2151 /* Set the function to be called as user data. */ 2152 n = 0; 2153 XtSetArg( args[ n ], XmNlabelString, items[ index ].label ); n++; 2154 XtSetArg( args[ n ], XmNuserData, (XtPointer) tbox ); n++; 2155 w = XmCreatePushButton( parent, 2156 ( items[ index ].name == NULL ? default_name : items[ index ].name ), 2157 args, n ); 2158 2159 /* For predefined actions, call common routine. 2160 For other actions, register as callbacks directly. */ 2161 if( ( items[ index ].proc != XmUbTB_NO_ACTION ) && 2162 ( (intptr_t)items[ index ].proc <= (intptr_t)XmUbTB_LAST_PREDEF_ACTION ) ) 2163 XtAddCallback( w, XmNactivateCallback, 2164 (XtCallbackProc) MenuItemActivatedCB, 2165 (XtPointer) items[ index ].proc ); 2166 2167 else if( items[ index ].proc != XmUbTB_NO_ACTION ) 2168 XtAddCallback( w, XmNactivateCallback, 2169 items[ index ].proc, items[ index ].client_data ); 2170 2171 break; 2172 2173 2174 default: 2175 /* Insert error message here !!!!!!! */ 2176 return; 2177 2178 } 2179 2180 XtManageChild( w ); 2181 2182 } /* for */ 2183 2184 2185 return; 2186 2187 } /* CreateMenuItems */ 2188 2189 2190 /*----------------------------------------------------------------------*/ 2191 2192 static Widget CreateTimeField(XmUbTimeBoxWidget tbox,char * name)2193 CreateTimeField( XmUbTimeBoxWidget tbox, 2194 char *name ) 2195 { 2196 2197 /* Variables. */ 2198 Arg args[ 5 ]; 2199 short columns; 2200 Cardinal n; 2201 char text_buffer[ TEXT_BUFFER_LENGTH ]; 2202 TIM_TIME_REF time; 2203 Widget w; 2204 2205 /* Code. */ 2206 2207 /* Find out how long the longest text in the time field is. */ 2208 /* Assume that 23:59 yields the longest text. */ 2209 time = TimMakeTime( 1970, 1, 1, 23, 59, 59 ); 2210 TimFormatTime( time, text_buffer, TEXT_BUFFER_LENGTH - 1 ); 2211 columns = (short) ( strlen( text_buffer ) + 1 ); 2212 2213 n = 0; 2214 XtSetArg( args[ n ], XmNeditMode, XmSINGLE_LINE_EDIT ); n++; 2215 XtSetArg( args[ n ], XmNcolumns, columns ); n++; 2216 XtSetArg( args[ n ], XmNtraversalOn, True ); n++; 2217 2218 w = XmCreateText( (Widget) tbox, name, args, n ); 2219 2220 /* We want to be able to pop up our own time selection dialog. */ 2221 XtOverrideTranslations( w, timeTextTranslations ); 2222 /* XtAugmentTranslations( w, timeTextTranslations ); */ 2223 2224 /* We want the completion callback when losing focus. */ 2225 XtAddCallback( w, XmNlosingFocusCallback, 2226 (XtCallbackProc) TimeCompletionCB, (XtPointer) tbox ); 2227 2228 /* Select all text when gaining focus. */ 2229 XtAddCallback( w, XmNfocusCallback, 2230 (XtCallbackProc) SelectAllTextCB, (XtPointer) tbox ); 2231 2232 XtAddCallback( w, XmNactivateCallback, 2233 (XtCallbackProc) ActivateCB, (XtPointer) tbox ); 2234 2235 XtAddCallback( w, XmNvalueChangedCallback, 2236 (XtCallbackProc) ValueChangedCB, (XtPointer) tbox ); 2237 2238 2239 return( w ); 2240 2241 } /* CreateTimeField */ 2242 2243 2244 /*----------------------------------------------------------------------*/ 2245 2246 static void CreateTimeSelectionPopup(XmUbTimeBoxWidget tbox)2247 CreateTimeSelectionPopup( XmUbTimeBoxWidget tbox ) 2248 { 2249 /* Variables. */ 2250 Arg args[ 8 ]; 2251 Widget cancel; 2252 Widget form; 2253 Dimension height, max_height; 2254 Cardinal n; 2255 char *name_buffer; 2256 Widget ok; 2257 Widget sep; 2258 Widget time_slider; 2259 Dimension width, max_width; 2260 String wname; 2261 2262 /* Code. */ 2263 2264 /* Reset flag that stop child creation temporarily. */ 2265 tbox -> tbox.internal_widgets_created = False; 2266 2267 /* Get the name of the "parent" widget. */ 2268 wname = XtName( (Widget)tbox ); 2269 2270 name_buffer = XtMalloc( strlen( wname ) + 6 ); 2271 2272 /* The dialog itself. */ 2273 sprintf( name_buffer, "%sTDi", wname ); 2274 2275 n = 0; 2276 form = XmCreateFormDialog( (Widget) tbox, name_buffer, args, n ); 2277 2278 tbox -> tbox.time_selection_popup = form; 2279 2280 /* In the form, we want a time slider, a separator and two buttons. */ 2281 sprintf( name_buffer, "%sTs", wname ); 2282 n = 0; 2283 XtSetArg( args[ n ], XmNmarginHeight, 10 ); n++; 2284 XtSetArg( args[ n ], XmNmarginWidth, 5 ); n++; 2285 XtSetArg( args[ n ], XmNwidth, 300 ); n++; 2286 2287 time_slider = XmUbCreateTimeSlider( form, name_buffer, args, n ); 2288 2289 sprintf( name_buffer, "%sTSep", wname ); 2290 2291 n = 0; 2292 XtSetArg( args[ n ], XmNorientation, XmHORIZONTAL ); n++; 2293 sep = XmCreateSeparator( form, name_buffer, args, n ); 2294 2295 sprintf( name_buffer, "%sTok", wname ); 2296 n = 0; 2297 XtSetArg( args[ n ], XmNlabelString, tbox -> tbox.ok_label ); n++; 2298 ok = XmCreatePushButton( form, name_buffer, args, n ); 2299 2300 sprintf( name_buffer, "%sTcan", wname ); 2301 n = 0; 2302 XtSetArg( args[ n ], XmNlabelString, tbox -> tbox.cancel_label ); n++; 2303 cancel = XmCreatePushButton( form, name_buffer, args, n ); 2304 2305 /* Attach the components. */ 2306 n = 0; 2307 XtSetArg( args[ n ], XmNtopAttachment, XmATTACH_FORM ); n++; 2308 XtSetArg( args[ n ], XmNleftAttachment, XmATTACH_FORM ); n++; 2309 XtSetArg( args[ n ], XmNrightAttachment, XmATTACH_FORM ); n++; 2310 XtSetArg( args[ n ], XmNbottomAttachment, XmATTACH_WIDGET ); n++; 2311 XtSetArg( args[ n ], XmNbottomWidget, sep ); n++; 2312 XtSetArg( args[ n ], XmNbottomOffset, 3 ); n++; 2313 XtSetValues( time_slider, args, n ); 2314 2315 n = 0; 2316 XtSetArg( args[ n ], XmNleftAttachment, XmATTACH_FORM ); n++; 2317 XtSetArg( args[ n ], XmNrightAttachment, XmATTACH_FORM ); n++; 2318 XtSetArg( args[ n ], XmNbottomAttachment, XmATTACH_WIDGET ); n++; 2319 XtSetArg( args[ n ], XmNbottomWidget, ok ); n++; 2320 XtSetArg( args[ n ], XmNbottomOffset, 3 ); n++; 2321 XtSetValues( sep, args, n ); 2322 2323 n = 0; 2324 XtSetArg( args[ n ], XmNleftAttachment, XmATTACH_FORM ); n++; 2325 XtSetArg( args[ n ], XmNleftOffset, 6 ); n++; 2326 XtSetArg( args[ n ], XmNbottomAttachment, XmATTACH_FORM ); n++; 2327 XtSetArg( args[ n ], XmNbottomOffset, 3 ); n++; 2328 XtSetValues( ok, args, n ); 2329 2330 n = 0; 2331 XtSetArg( args[ n ], XmNrightAttachment, XmATTACH_FORM ); n++; 2332 XtSetArg( args[ n ], XmNrightOffset, 6 ); n++; 2333 XtSetArg( args[ n ], XmNbottomAttachment, XmATTACH_FORM ); n++; 2334 XtSetArg( args[ n ], XmNbottomOffset, 3 ); n++; 2335 XtSetValues( cancel, args, n ); 2336 2337 2338 /* Set resources on the shell. */ 2339 n = 0; 2340 XtSetArg( args[ n ], XmNdeleteResponse, XmDO_NOTHING ); n++; 2341 if( tbox -> tbox.time_selection_title != NULL ){ 2342 XtSetArg( args[ n ], XmNtitle, tbox -> tbox.time_selection_title ); n++; 2343 } else { 2344 XtSetArg( args[ n ], XmNtitle, default_time_selection_title ); n++; 2345 } 2346 2347 XtSetValues( XtParent( form ), args, n ); 2348 2349 /* We must catch close events on the shell and prevent it from being 2350 destroyed. */ 2351 XmAddProtocolCallback( XtParent( form ), protocol_atom, delete_atom, 2352 (XtCallbackProc) PopdownTimeSelectionDialogCB, 2353 (XtPointer) tbox ); 2354 2355 /* Callbacks. */ 2356 XtAddCallback( time_slider, XmNactivateCallback, 2357 (XtCallbackProc) TimeSelectedInDialogCB, (XtPointer) tbox ); 2358 XtAddCallback( ok, XmNactivateCallback, 2359 (XtCallbackProc) TimeSelectedInDialogCB, (XtPointer) tbox ); 2360 XtAddCallback( cancel, XmNactivateCallback, 2361 (XtCallbackProc) PopdownTimeSelectionDialogCB, 2362 (XtPointer) tbox ); 2363 2364 2365 /* Manage the internal widget (but not the form!) */ 2366 XtManageChild( time_slider ); 2367 XtManageChild( sep ); 2368 XtManageChild( ok ); 2369 XtManageChild( cancel ); 2370 2371 /* Set both buttons the same size. */ 2372 n = 0; 2373 XtSetArg( args[ n ], XmNwidth, &width ); n++; 2374 XtSetArg( args[ n ], XmNheight, &height ); n++; 2375 XtGetValues( ok, args, n ); 2376 2377 max_width = width; 2378 max_height = height; 2379 2380 XtGetValues( cancel, args, n ); 2381 2382 if( width > max_width ) 2383 max_width = width; 2384 if( height > max_height ) 2385 max_height = height; 2386 2387 n = 0; 2388 XtSetArg( args[ n ], XmNwidth, max_width ); n++; 2389 XtSetArg( args[ n ], XmNheight, max_height ); n++; 2390 XtSetValues( ok, args, n ); 2391 XtSetValues( cancel, args, n ); 2392 2393 /* Cleanup. */ 2394 XtFree( name_buffer ); 2395 2396 /* Back to stopping child widgets. */ 2397 tbox -> tbox.internal_widgets_created = True; 2398 2399 2400 return; 2401 2402 } /* CreateTimeSelectionPopup */ 2403 2404 2405 /*----------------------------------------------------------------------*/ 2406 2407 static void DateCompletionCB(Widget tw,XmUbTimeBoxWidget tbox,XmTextVerifyCallbackStruct * call_data)2408 DateCompletionCB( Widget tw, 2409 XmUbTimeBoxWidget tbox, 2410 XmTextVerifyCallbackStruct *call_data ) 2411 { 2412 /* Variables. */ 2413 int child_index; 2414 Boolean restart; 2415 XmUbTimeBoxStatus status; 2416 2417 /* Code. */ 2418 2419 DateCompletionCB_START: 2420 2421 /* Find child index for this field. */ 2422 child_index = ChildIndex( tbox, tw ); 2423 2424 /* Completion is different depending on which field we are dealing with. */ 2425 switch( child_index ){ 2426 2427 case XmUbTB_CHILD_START_DATE: 2428 status = CompleteStartDate( tbox ); 2429 break; 2430 2431 2432 case XmUbTB_CHILD_END_DATE: 2433 status = CompleteEndDate( tbox ); 2434 break; 2435 2436 default: 2437 /* This should not happen. */ 2438 printf( "DateCompletionCB ERROR, called for wrong child.\n" ); 2439 return; 2440 2441 } /* switch */ 2442 2443 /* Issue the callback(s). */ 2444 restart = TimeCompletionCallback( tw, child_index, tbox, 2445 (XmAnyCallbackStruct *) call_data, 2446 status ); 2447 if( restart ) 2448 goto DateCompletionCB_START; 2449 2450 2451 return; 2452 2453 } /* DateCompletionCB */ 2454 2455 2456 /*----------------------------------------------------------------------*/ 2457 2458 #if XmVersion > 1001 2459 2460 static void DateDropCB(Widget w,XtPointer client_data,XmDropProcCallbackStruct * drop_data)2461 DateDropCB( Widget w, 2462 XtPointer client_data, 2463 XmDropProcCallbackStruct *drop_data ) 2464 { 2465 /* Variables. */ 2466 Arg args[ 5 ]; 2467 Atom compound_text_atom; 2468 Atom date_transfer_atom; 2469 Atom *export_list; 2470 int index; 2471 XmTextPosition insert_pos; 2472 Cardinal n; 2473 Cardinal num_exports; 2474 int num_transfers = 0; 2475 XmDropTransferEntryRec transfer_entries[ 2 ]; 2476 XmDropTransferEntry transfer_list; 2477 2478 /* Code. */ 2479 2480 compound_text_atom = XmInternAtom( XtDisplay( w ), "COMPOUND_TEXT", False ); 2481 date_transfer_atom = XmInternAtom( XtDisplay( w ), XmUbDATE_TRANSFER, 2482 False ); 2483 2484 /* Set the transfer resources. */ 2485 n = 0; 2486 2487 /* Cancel the drop if the action is not a drop or if user wants a link. */ 2488 if( ( drop_data -> dropAction != XmDROP ) || 2489 ( drop_data -> operation == XmDROP_LINK ) ){ 2490 XtSetArg( args[ n ], XmNtransferStatus, XmTRANSFER_FAILURE ); n++; 2491 2492 } else { 2493 /* Go on with the drop. Establish the transfer list and start transfer. */ 2494 2495 /* Get the exported targets for the drag context and select the 2496 desired one. */ 2497 n = 0; 2498 XtSetArg( args[ n ], XmNexportTargets, &export_list ); n++; 2499 XtSetArg( args[ n ], XmNnumExportTargets, &num_exports ); n++; 2500 XtGetValues( drop_data -> dragContext, args, n ); 2501 2502 /* Our preferred format is date transfer. See if we can find it. */ 2503 for( index = 0; index < num_exports; index ++ ){ 2504 2505 if( export_list[ index ] == date_transfer_atom ){ 2506 transfer_entries[ 0 ].target = date_transfer_atom; 2507 transfer_entries[ 0 ].client_data = (XtPointer) w; 2508 num_transfers = 1; 2509 2510 break; 2511 } 2512 } 2513 2514 /* Alternative format is compound text. */ 2515 if( num_transfers == 0 ){ 2516 2517 for( index = 0; index < num_exports; index ++ ){ 2518 2519 if( export_list[ index ] == compound_text_atom ){ 2520 transfer_entries[ 0 ].target = compound_text_atom; 2521 transfer_entries[ 0 ].client_data = (XtPointer) w; 2522 num_transfers = 1; 2523 2524 /* The text should be inserted at the drop position. */ 2525 insert_pos = XmTextXYToPos( w, drop_data -> x, drop_data -> y ); 2526 XmTextSetInsertionPosition( w, insert_pos ); 2527 2528 break; 2529 } 2530 } 2531 } 2532 2533 transfer_list = transfer_entries; 2534 2535 XtSetArg( args[ n ], XmNdropTransfers, transfer_list ); n++; 2536 XtSetArg( args[ n ], XmNnumDropTransfers, num_transfers ); n++; 2537 XtSetArg( args[ n ], XmNtransferProc, TransferDateField ); n++; 2538 } 2539 2540 /* Start the transfer or cancel. */ 2541 XmDropTransferStart( drop_data -> dragContext, args, n ); 2542 2543 2544 return; 2545 2546 } /* DateDropCB */ 2547 2548 #endif 2549 2550 /*----------------------------------------------------------------------*/ 2551 2552 static void DeleteChild(Widget widget)2553 DeleteChild( Widget widget ) 2554 { 2555 2556 /* Variables. */ 2557 int index; 2558 XmUbTimeBoxWidget tbox; 2559 2560 /* Code. */ 2561 2562 tbox = (XmUbTimeBoxWidget) XtParent( widget ); 2563 2564 /* Clear the internal reference. */ 2565 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ){ 2566 if( tbox -> tbox.internal_children[ index ] == widget ){ 2567 tbox -> tbox.internal_children[ index ] = NULL; 2568 break; 2569 } 2570 } 2571 2572 /* Perform the actual operation */ 2573 (* ( (CompositeWidgetClass) (xmUbTimeBoxWidgetClass -> 2574 core_class.superclass) ) -> composite_class.delete_child ) ( widget ); 2575 2576 2577 return; 2578 2579 } /* DeleteChild */ 2580 2581 2582 /*----------------------------------------------------------------------*/ 2583 2584 static void Destroy(Widget widget)2585 Destroy( Widget widget ) 2586 { 2587 /* Variables. */ 2588 XmUbTimeBoxWidget tbox; 2589 2590 /* Code. */ 2591 2592 tbox = (XmUbTimeBoxWidget) widget; 2593 2594 /* Free the copied strings. */ 2595 if( tbox -> tbox.year_marker != NULL ) 2596 XtFree( tbox -> tbox.year_marker ); 2597 if( tbox -> tbox.month_marker != NULL ) 2598 XtFree( tbox -> tbox.month_marker ); 2599 if( tbox -> tbox.week_marker != NULL ) 2600 XtFree( tbox -> tbox.week_marker ); 2601 if( tbox -> tbox.day_marker != NULL ) 2602 XtFree( tbox -> tbox.day_marker ); 2603 if( tbox -> tbox.hour_marker != NULL ) 2604 XtFree( tbox -> tbox.hour_marker ); 2605 if( tbox -> tbox.minute_marker != NULL ) 2606 XtFree( tbox -> tbox.minute_marker ); 2607 2608 if( tbox -> tbox.time_selection_title != NULL ) 2609 XtFree( tbox -> tbox.time_selection_title ); 2610 if( tbox -> tbox.date_selection_title != NULL ) 2611 XtFree( tbox -> tbox.date_selection_title ); 2612 2613 /* Free XmStrings. */ 2614 if( tbox -> tbox.ok_label != NULL ) 2615 XmStringFree( tbox -> tbox.ok_label ); 2616 if( tbox -> tbox.cancel_label != NULL ) 2617 XmStringFree( tbox -> tbox.cancel_label ); 2618 if( tbox -> tbox.week_label != NULL ) 2619 XmStringFree( tbox -> tbox.week_label ); 2620 if( tbox -> tbox.month_label != NULL ) 2621 XmStringFree( tbox -> tbox.month_label ); 2622 if( tbox -> tbox.year_label != NULL ) 2623 XmStringFree( tbox -> tbox.year_label ); 2624 2625 /* Remove callbacks. */ 2626 XtRemoveAllCallbacks( widget, XmNactivateCallback ); 2627 XtRemoveAllCallbacks( widget, XmNvalueChangedCallback ); 2628 XtRemoveAllCallbacks( widget, XmUbNtboxCompletionCallback ); 2629 2630 2631 return; 2632 2633 } /* Destroy */ 2634 2635 2636 /*----------------------------------------------------------------------*/ 2637 2638 static void DoLayout(XmUbTimeBoxWidget tbox,Widget initiator,XtWidgetGeometry * request,KidDimensionRec sizes[])2639 DoLayout( XmUbTimeBoxWidget tbox, 2640 Widget initiator, 2641 XtWidgetGeometry *request, 2642 KidDimensionRec sizes[] ) 2643 { 2644 /* Variables. */ 2645 int index; 2646 Widget kid; 2647 2648 /* Code. */ 2649 2650 /* All positions and dimensions are in the sizes array. */ 2651 if( tbox -> tbox.menu_enabled && 2652 ( tbox -> tbox.internal_children[ XmUbTB_CHILD_MENU_BAR ] != NULL ) ){ 2653 2654 index = XmUbTB_CHILD_MENU_BAR; 2655 kid = tbox -> tbox.internal_children[ index ]; 2656 2657 XtConfigureWidget( kid, sizes[ index ].x, sizes[ index ].y, 2658 sizes[ index ].width, sizes[ index ].height, kid -> core.border_width ); 2659 } 2660 2661 /* Loop for the text widgets. */ 2662 for( index = XmUbTB_CHILD_START_DATE; index < NO_INTERNAL_CHILDREN; 2663 index ++ ){ 2664 2665 kid = tbox -> tbox.internal_children[ index ]; 2666 2667 if( ( kid != NULL ) && XtIsManaged( kid ) ) 2668 XtConfigureWidget( kid, sizes[ index ].x, sizes[ index ].y, 2669 sizes[ index ].width, sizes[ index ].height, 2670 kid -> core.border_width ); 2671 } 2672 2673 2674 return; 2675 2676 } /* DoLayout */ 2677 2678 2679 /*----------------------------------------------------------------------*/ 2680 2681 static void DateSelectedInDialogCB(Widget md,XmUbTimeBoxWidget tbox,XmUbMonthDisplayCallbackStruct * call_data)2682 DateSelectedInDialogCB( Widget md, 2683 XmUbTimeBoxWidget tbox, 2684 XmUbMonthDisplayCallbackStruct *call_data ) 2685 { 2686 /* Variables. */ 2687 char buffer[ TIME_STRING_BUFFER_LEN ]; 2688 XmUbTimeBoxCallbackStruct cb; 2689 Boolean known_field = True; 2690 TIM_TIME_REF time; 2691 2692 /* Code. */ 2693 2694 /* Get the selected date. */ 2695 time = TimMakeTime( call_data -> selected_year, call_data -> selected_month, 2696 call_data -> selected_day, 0, 0, 0 ); 2697 2698 /* Create the string. */ 2699 TimFormatDate( time, buffer, TIME_STRING_BUFFER_LEN - 1 ); 2700 2701 if( call_data -> range ){ 2702 2703 /* The first date is the start date. */ 2704 (void) XmUbTimeBoxSetStartDateString( (Widget) tbox, buffer ); 2705 2706 /* Set the end date too. */ 2707 time = TimMakeTime( call_data -> end_year, call_data -> end_month, 2708 call_data -> end_day, 0, 0, 0 ); 2709 TimFormatDate( time, buffer, TIME_STRING_BUFFER_LEN - 1 ); 2710 2711 (void) XmUbTimeBoxSetEndDateString( (Widget) tbox, buffer ); 2712 2713 } else { 2714 2715 switch( tbox -> tbox.field_for_date_selection ){ 2716 2717 case XmUbTB_CHILD_START_DATE: 2718 (void) XmUbTimeBoxSetStartDateString( (Widget) tbox, buffer ); 2719 break; 2720 2721 case XmUbTB_CHILD_END_DATE: 2722 (void) XmUbTimeBoxSetEndDateString( (Widget) tbox, buffer ); 2723 break; 2724 2725 default: 2726 known_field = False; 2727 break; 2728 } 2729 } 2730 2731 /* We have to call the callback to pop down the dialog here, since it 2732 might destroy the widget. */ 2733 PopdownDateSelectionDialogCB( md, tbox, (XmAnyCallbackStruct *) call_data ); 2734 2735 /* Call activate callback. */ 2736 if( known_field && ( tbox -> tbox.activate_callback != NULL ) ){ 2737 2738 /* Set up callback structure. */ 2739 2740 cb.reason = XmUbCR_DATE_PICKED; 2741 cb.event = NULL; 2742 cb.child_index = tbox -> tbox.field_for_date_selection; 2743 cb.child = tbox -> tbox.internal_children[ cb.child_index ]; 2744 cb.range = call_data -> range; 2745 2746 XtCallCallbackList( (Widget) tbox, tbox -> tbox.activate_callback, 2747 (XtPointer) &cb ); 2748 } 2749 2750 2751 return; 2752 2753 } /* DateSelectedInDialogCB */ 2754 2755 2756 /*----------------------------------------------------------------------*/ 2757 2758 static void FillInStartOfMonth(XmUbTimeBoxWidget tbox)2759 FillInStartOfMonth( XmUbTimeBoxWidget tbox ) 2760 { 2761 /* Variables. */ 2762 TIM_TIME_REF now; 2763 TIM_TIME_REF tloc; 2764 int month, year; 2765 2766 /* Code. */ 2767 2768 /* Get the start date of the week and display it in the text field. */ 2769 now = TimMakeTimeNow(); 2770 tloc = TimLocalTime( now ); 2771 2772 year = TimIndexOfYear( tloc ); 2773 month = TimIndexOfMonth( tloc ); 2774 2775 /* Get start of week. */ 2776 tloc = TimMakeTime( year, month, 1, 0, 0, 0 ); 2777 2778 (void) XmUbTimeBoxSetStartDate( (Widget) tbox, tloc ); 2779 (void) XmUbTimeBoxSetStartTime( (Widget) tbox, tloc ); 2780 2781 2782 return; 2783 2784 } /* FillInStartOfMonth */ 2785 2786 2787 /*----------------------------------------------------------------------*/ 2788 2789 static void FillInStartOfWeek(XmUbTimeBoxWidget tbox)2790 FillInStartOfWeek( XmUbTimeBoxWidget tbox ) 2791 { 2792 /* Variables. */ 2793 TIM_TIME_REF now; 2794 TIM_STATUS_TYPE status; 2795 TIM_TIME_REF tloc; 2796 int week, year; 2797 2798 /* Code. */ 2799 2800 /* Get the start date of the week and display it in the text field. */ 2801 now = TimMakeTimeNow(); 2802 tloc = TimLocalTime( now ); 2803 2804 year = TimIndexOfYear( tloc ); 2805 week = TimIndexOfWeek( tloc ); 2806 2807 /* Get start of week. */ 2808 status = TimMakeTimeFromWeek( year, week, &tloc ); 2809 if( status != TIM_OK ) 2810 return; 2811 2812 (void) XmUbTimeBoxSetStartDate( (Widget) tbox, tloc ); 2813 (void) XmUbTimeBoxSetStartTime( (Widget) tbox, tloc ); 2814 2815 2816 return; 2817 2818 } /* FillInStartOfWeek */ 2819 2820 2821 /*----------------------------------------------------------------------*/ 2822 2823 static XtGeometryResult GeometryManager(Widget widget,XtWidgetGeometry * request,XtWidgetGeometry * reply)2824 GeometryManager( Widget widget, 2825 XtWidgetGeometry *request, 2826 XtWidgetGeometry *reply ) 2827 { 2828 2829 XtWidgetGeometry own_request; 2830 Dimension old_width, old_height; 2831 Dimension pref_height; 2832 Dimension pref_width; 2833 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 2834 XtGeometryResult result; 2835 XmUbTimeBoxWidget tbox; 2836 2837 /* Code. */ 2838 2839 tbox = (XmUbTimeBoxWidget) XtParent( widget ); 2840 2841 /* Find out how big the widget would be if the resize were allowed. */ 2842 GetChildPrefSizes( tbox, NULL, request, kids_sizes ); 2843 PrepareLayout( tbox, kids_sizes, &pref_width, &pref_height ); 2844 2845 /* If no change in dimensions, allow the request. */ 2846 if( ( pref_width == tbox -> core.width ) && 2847 ( pref_height == tbox -> core.height )){ 2848 DoLayout( tbox, widget, request, kids_sizes ); 2849 return XtGeometryYes; 2850 } 2851 2852 /* We must ask our parent to resize us. */ 2853 own_request.request_mode = CWWidth | CWHeight; 2854 own_request.width = pref_width; 2855 own_request.height = pref_height; 2856 2857 /* Save dimensions. */ 2858 old_width = tbox -> core.width; 2859 old_height = tbox -> core.height; 2860 2861 tbox -> tbox.resize_called = False; 2862 2863 /* We are not interested in any compromise geometry. */ 2864 result = XtMakeGeometryRequest( (Widget) tbox, &own_request, NULL ); 2865 2866 /* Reset to old dimensions if request not granted. */ 2867 if( result != XtGeometryYes ){ 2868 tbox -> core.width = old_width; 2869 tbox -> core.height = old_height; 2870 2871 } else { 2872 if( !tbox -> tbox.resize_called ) 2873 Resize( (Widget) tbox ); 2874 } 2875 2876 /* Always grant child's request. */ 2877 return XtGeometryYes; 2878 2879 } /* GeometryManager */ 2880 2881 2882 /*----------------------------------------------------------------------*/ 2883 2884 static void GetChildPrefSizes(XmUbTimeBoxWidget tbox,Widget initiator,XtWidgetGeometry * request,KidDimensionRec sizes[])2885 GetChildPrefSizes( XmUbTimeBoxWidget tbox, 2886 Widget initiator, 2887 XtWidgetGeometry *request, 2888 KidDimensionRec sizes[] ) 2889 { 2890 /* Variables. */ 2891 XtWidgetGeometry desired; 2892 int index; 2893 Widget kid; 2894 2895 /* Code. */ 2896 2897 /* Initialize. */ 2898 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ){ 2899 sizes[ index ].width = 0; 2900 sizes[ index ].height = 0; 2901 sizes[ index ].x = 0; 2902 sizes[ index ].y = 0; 2903 } 2904 2905 /* Get the preferred sizes for the children. */ 2906 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ){ 2907 2908 /* The pulldown menu should not be considered. */ 2909 if( ( index == XmUbTB_CHILD_MENU_PD ) || 2910 ( index == XmUbTB_CHILD_MENU_CASC ) ) 2911 continue; 2912 2913 kid = tbox -> tbox.internal_children[ index ]; 2914 2915 if( ( kid != NULL ) && XtIsManaged( kid ) ){ 2916 2917 KidsPreferredGeometry( kid, initiator, request, &desired ); 2918 2919 sizes[ index ].width = desired.width; 2920 sizes[ index ].height = desired.height; 2921 2922 } 2923 2924 } /* for */ 2925 2926 2927 return; 2928 2929 } /* GetChildPrefSizes */ 2930 2931 2932 /*----------------------------------------------------------------------*/ 2933 2934 XmUbTimeBoxStatus GetChildString(XmUbTimeBoxWidget tbox,int child,char ** str)2935 GetChildString( XmUbTimeBoxWidget tbox, 2936 int child, 2937 char **str ) 2938 { 2939 /* Variables. */ 2940 Widget tw; 2941 2942 /* Code. */ 2943 2944 tw = tbox -> tbox.internal_children[ child ]; 2945 if( tw == NULL ) 2946 return( TBOX_NO_FIELD ); 2947 2948 *str = XmTextGetString( tw ); 2949 2950 /* For an empty string, we return a status value. */ 2951 if( strlen( *str ) == 0 ){ 2952 XtFree( *str ); 2953 return( TBOX_EMPTY ); 2954 } 2955 2956 return( TBOX_OK ); 2957 2958 } /* GetChildString */ 2959 2960 2961 /*----------------------------------------------------------------------*/ 2962 2963 XmUbTimeBoxStatus GetStartDateTime(XmUbTimeBoxWidget tbox,Boolean use_defaults,TIM_TIME_REF * date_time)2964 GetStartDateTime( XmUbTimeBoxWidget tbox, 2965 Boolean use_defaults, 2966 TIM_TIME_REF *date_time ) 2967 { 2968 /* Variables. */ 2969 TIM_TIME_REF date; 2970 XmUbTimeBoxStatus status; 2971 TIM_TIME_REF time; 2972 2973 /* Code. */ 2974 2975 status = XmUbTimeBoxGetStartDate( (Widget) tbox, &date ); 2976 if( status != TBOX_OK ){ 2977 if( use_defaults ) 2978 date = TimMakeTime( 1970, 1, 1, 0, 0, 0 ); 2979 else 2980 return( status ); 2981 } 2982 2983 status = XmUbTimeBoxGetStartTime( (Widget) tbox, &time ); 2984 if( status != TBOX_OK ){ 2985 if( use_defaults ) 2986 time = TimMakeTime( 1970, 1, 1, 0, 0, 0 ); 2987 else 2988 return( status ); 2989 } 2990 2991 /* Construct combined time. */ 2992 *date_time = CombineDateAndTime( date, time ); 2993 2994 2995 return( TBOX_OK ); 2996 2997 } /* GetStartDateTime */ 2998 2999 3000 /*----------------------------------------------------------------------*/ 3001 3002 static void GetValuesHook(Widget w,ArgList args,Cardinal * num_args)3003 GetValuesHook( Widget w, 3004 ArgList args, 3005 Cardinal *num_args ) 3006 { 3007 /* Variables. */ 3008 int index; 3009 XmUbTimeBoxWidget tbox; 3010 3011 /* Code. */ 3012 3013 tbox = (XmUbTimeBoxWidget) w; 3014 3015 /* Copy the XmStrings. */ 3016 for( index = 0; index < *num_args; index ++ ){ 3017 3018 if( strcmp( args[ index ].name, XmNcancelLabelString ) == 0 ){ 3019 * ( XmString *) ( args[ index ].value ) = 3020 XmStringCopy( tbox -> tbox.cancel_label ); 3021 3022 } else if( strcmp( args[ index ].name, XmNokLabelString ) == 0 ){ 3023 * ( XmString *) ( args[ index ].value ) = 3024 XmStringCopy( tbox -> tbox.ok_label ); 3025 3026 } else if( strcmp( args[ index ].name, XmUbNtboxMonthLabel ) == 0 ){ 3027 * ( XmString *) ( args[ index ].value ) = 3028 XmStringCopy( tbox -> tbox.month_label ); 3029 3030 } else if( strcmp( args[ index ].name, XmUbNtboxWeekLabel ) == 0 ){ 3031 * ( XmString *) ( args[ index ].value ) = 3032 XmStringCopy( tbox -> tbox.week_label ); 3033 3034 } else if( strcmp( args[ index ].name, XmUbNtboxYearLabel ) == 0 ){ 3035 * ( XmString *) ( args[ index ].value ) = 3036 XmStringCopy( tbox -> tbox.year_label ); 3037 3038 } 3039 } 3040 3041 3042 return; 3043 3044 } /* GetValuesHook */ 3045 3046 3047 /*----------------------------------------------------------------------*/ 3048 3049 static void Initialize(Widget treq,Widget tnew,ArgList args,Cardinal * num_args)3050 Initialize( Widget treq, 3051 Widget tnew, 3052 ArgList args, 3053 Cardinal *num_args ) 3054 { 3055 3056 /* Variables. */ 3057 int index; 3058 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 3059 XmUbTimeBoxWidget new; 3060 char *newstr; 3061 Dimension pref_width; 3062 Dimension pref_height; 3063 char *str; 3064 XmString xm; 3065 3066 /* Code. */ 3067 3068 new = (XmUbTimeBoxWidget) tnew; 3069 3070 /* Initialize private fields. */ 3071 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ) 3072 new -> tbox.internal_children[ index ] = NULL; 3073 3074 new -> tbox.time_selection_popup = NULL; 3075 new -> tbox.date_selection_popup = NULL; 3076 3077 new -> tbox.field_for_time_selection = XmUbTB_CHILD_START_TIME; 3078 new -> tbox.field_for_date_selection = XmUbTB_CHILD_START_DATE; 3079 3080 /* Start size if none supplied. */ 3081 if( new -> core.width == 0 ) 3082 new -> core.width = 100; 3083 if( new -> core.height == 0 ) 3084 new -> core.height = 100; 3085 3086 /* The atoms must be set up here, since we need a display varaible for it. */ 3087 if( ! context_dependent_done ){ 3088 protocol_atom = XmInternAtom( XtDisplay( tnew ), "WM_PROTOCOLS", False ); 3089 delete_atom = XmInternAtom( XtDisplay( tnew ), 3090 "WM_DELETE_WINDOW", False ); 3091 3092 context_dependent_done = True; 3093 } 3094 3095 /* Copy XmStrings and/or use defaults. */ 3096 if( new -> tbox.ok_label == NULL ) 3097 xm = XmStringCreateLtoR( default_ok_string, XmSTRING_DEFAULT_CHARSET ); 3098 else 3099 xm = XmStringCopy( new -> tbox.ok_label ); 3100 new -> tbox.ok_label = xm; 3101 3102 if( new -> tbox.cancel_label == NULL ) 3103 xm = XmStringCreateLtoR( default_cancel_string, XmSTRING_DEFAULT_CHARSET ); 3104 else 3105 xm = XmStringCopy( new -> tbox.cancel_label ); 3106 new -> tbox.cancel_label = xm; 3107 3108 if( new -> tbox.week_label != NULL ){ 3109 xm = XmStringCopy( new -> tbox.week_label ); 3110 new -> tbox.week_label = xm; 3111 } 3112 if( new -> tbox.month_label != NULL ){ 3113 xm = XmStringCopy( new -> tbox.month_label ); 3114 new -> tbox.month_label = xm; 3115 } 3116 if( new -> tbox.year_label != NULL ){ 3117 xm = XmStringCopy( new -> tbox.year_label ); 3118 new -> tbox.year_label = xm; 3119 } 3120 3121 /* Copy title strings. */ 3122 if( new -> tbox.time_selection_title != NULL ){ 3123 str = XtMalloc( strlen( new -> tbox.time_selection_title ) + 1 ); 3124 strcpy( str, new -> tbox.time_selection_title ); 3125 new -> tbox.time_selection_title = str; 3126 } 3127 if( new -> tbox.date_selection_title != NULL ){ 3128 str = XtMalloc( strlen( new -> tbox.date_selection_title ) + 1 ); 3129 strcpy( str, new -> tbox.date_selection_title ); 3130 new -> tbox.date_selection_title = str; 3131 } 3132 3133 3134 /* Copy strings for scanning. */ 3135 #define SetMarker( field, default ) \ 3136 { \ 3137 if( field == NULL ){ \ 3138 newstr = XtMalloc( strlen( default )+1 ); \ 3139 strcpy( newstr, default ); \ 3140 field = newstr; \ 3141 } else { \ 3142 newstr = XtMalloc( strlen( field )+1 ); \ 3143 strcpy( newstr, field ); \ 3144 field = newstr; \ 3145 } \ 3146 } 3147 3148 SetMarker( new -> tbox.day_marker, default_day_marker ); 3149 SetMarker( new -> tbox.hour_marker, default_hour_marker ); 3150 SetMarker( new -> tbox.minute_marker, default_minute_marker ); 3151 SetMarker( new -> tbox.month_marker, default_month_marker ); 3152 SetMarker( new -> tbox.week_marker, default_week_marker ); 3153 SetMarker( new -> tbox.year_marker, default_year_marker ); 3154 3155 #undef SetMarker 3156 3157 3158 /* Create the internal widgets. */ 3159 new -> tbox.internal_widgets_created = False; 3160 3161 CreateInternalWidgets( new ); 3162 3163 new -> tbox.internal_widgets_created = True; 3164 3165 3166 /* Set the desired dimensions of the widget. */ 3167 GetChildPrefSizes( new, NULL, NULL, kids_sizes ); 3168 PrepareLayout( new, kids_sizes, &pref_width, &pref_height ); 3169 3170 new -> core.width = pref_width; 3171 new -> core.height = pref_height; 3172 3173 DoLayout( new, NULL, NULL, kids_sizes ); 3174 3175 3176 return; 3177 3178 } /* Initialize */ 3179 3180 3181 /*----------------------------------------------------------------------*/ 3182 3183 static void InitializeItem(int index,XmUbMenuItem items[],XmUbItem item,String label,XtCallbackProc proc,XtPointer client_data)3184 InitializeItem( int index, 3185 XmUbMenuItem items[], 3186 XmUbItem item, 3187 String label, 3188 XtCallbackProc proc, 3189 XtPointer client_data ) 3190 { 3191 /* Variables. */ 3192 3193 /* Code. */ 3194 3195 items[ index ].item = item; 3196 3197 items[ index ].name = XtMalloc( 5 ); 3198 if( item == XmUbITEM_PUSH_BUTTON ) 3199 sprintf( items[ index ].name, "Bu%d", index ); 3200 else 3201 sprintf( items[ index ].name, "Sep%d", index ); 3202 3203 items[ index ].label = XmStringCreateLtoR( label, XmSTRING_DEFAULT_CHARSET ); 3204 3205 items[ index ].proc = proc; 3206 items[ index ].client_data = client_data; 3207 3208 3209 return; 3210 3211 } /* InitializeItem */ 3212 3213 3214 /*----------------------------------------------------------------------*/ 3215 3216 static void InitializeDefaultMenu(XmUbTimeBoxWidget tbox,XmUbMenuItem items[],int * num_items_created)3217 InitializeDefaultMenu( XmUbTimeBoxWidget tbox, 3218 XmUbMenuItem items[], 3219 int *num_items_created ) 3220 { 3221 /* Variables. */ 3222 int n = 0; 3223 3224 /* Code. */ 3225 3226 /* The items in the menu depend on the widget format. */ 3227 3228 /* The first field applies to all formats. */ 3229 InitializeItem( n++, items, XmUbITEM_PUSH_BUTTON, 3230 "Now", XmUbTB_ACTION_NOW, NULL ); 3231 3232 /* These apply only to ranges with two date fields. */ 3233 if( ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DD ) || 3234 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTDT ) ){ 3235 3236 InitializeItem( n++, items, XmUbITEM_SEPARATOR, 3237 "", XmUbTB_NO_ACTION, NULL ); 3238 InitializeItem( n++, items, XmUbITEM_PUSH_BUTTON, 3239 "This week", XmUbTB_ACTION_THIS_WEEK, NULL ); 3240 InitializeItem( n++, items, XmUbITEM_PUSH_BUTTON, 3241 "This month", XmUbTB_ACTION_THIS_MONTH, NULL ); 3242 } 3243 3244 /* The following apply to range fields that include the time. */ 3245 if( ( tbox -> tbox.widget_format == XmUbTB_FORMAT_TT ) || 3246 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTT ) || 3247 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTDT ) ){ 3248 3249 InitializeItem( n++, items, XmUbITEM_SEPARATOR, 3250 "", XmUbTB_NO_ACTION, NULL ); 3251 InitializeItem( n++, items, XmUbITEM_PUSH_BUTTON, 3252 "+ One Hour", XmUbTB_ACTION_PLUS_ONE_HOUR, NULL ); 3253 InitializeItem( n++, items, XmUbITEM_PUSH_BUTTON, 3254 "+ Two Hours", XmUbTB_ACTION_PLUS_TWO_HOURS, NULL ); 3255 } 3256 3257 /* These apply to ranges with date fields. */ 3258 if( ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DD ) || 3259 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTDT ) ){ 3260 3261 InitializeItem( n++, items, XmUbITEM_SEPARATOR, 3262 "", XmUbTB_NO_ACTION, NULL ); 3263 InitializeItem( n++, items, XmUbITEM_PUSH_BUTTON, 3264 "+ One Week", XmUbTB_ACTION_PLUS_ONE_WEEK, NULL ); 3265 InitializeItem( n++, items, XmUbITEM_PUSH_BUTTON, 3266 "+ Two Weeks", XmUbTB_ACTION_PLUS_TWO_WEEKS, NULL ); 3267 InitializeItem( n++, items, XmUbITEM_PUSH_BUTTON, 3268 "+ One Month", XmUbTB_ACTION_PLUS_ONE_MONTH, NULL ); 3269 } 3270 3271 3272 *num_items_created = n; 3273 3274 return; 3275 3276 } /* InitializeDefaultMenu */ 3277 3278 3279 /*----------------------------------------------------------------------*/ 3280 3281 static void InsertChild(Widget widget)3282 InsertChild( Widget widget ) 3283 { 3284 3285 /* Variables. */ 3286 Cardinal num_params; 3287 String params[ 1 ]; 3288 XmUbTimeBoxWidget tbox; 3289 3290 /* Code. */ 3291 3292 tbox = (XmUbTimeBoxWidget) XtParent( widget ); 3293 3294 /* We do not allow the application to create children. */ 3295 if( tbox -> tbox.internal_widgets_created ){ 3296 3297 params[ 0 ] = XtClass( tbox ) -> core_class.class_name; 3298 num_params = 1; 3299 XtAppErrorMsg( XtWidgetToApplicationContext( widget ), 3300 "childError", "number", "WidgetError", 3301 "Applications cannot add children to %s widgets.", 3302 params, &num_params ); 3303 } 3304 3305 /* This is an internal child. Adding it is OK. */ 3306 (* ( (CompositeWidgetClass) (xmUbTimeBoxWidgetClass -> 3307 core_class.superclass) ) -> composite_class.insert_child ) ( widget ); 3308 3309 3310 return; 3311 3312 } /* InsertChild */ 3313 3314 3315 /*----------------------------------------------------------------------*/ 3316 3317 static void KidsPreferredGeometry(Widget kid,Widget initiator,XtWidgetGeometry * request,XtWidgetGeometry * desired)3318 KidsPreferredGeometry( Widget kid, 3319 Widget initiator, 3320 XtWidgetGeometry *request, 3321 XtWidgetGeometry *desired ) 3322 { 3323 3324 /* Code. */ 3325 3326 if( ( kid == initiator ) && ( request != NULL ) ){ 3327 /* The initiator should not be queried. */ 3328 if( request -> request_mode & CWWidth ) 3329 desired -> width = request -> width; 3330 else 3331 desired -> width = (Dimension) kid -> core.width; 3332 3333 if( request -> request_mode & CWHeight ) 3334 desired -> height = request -> height; 3335 else 3336 desired -> height = (Dimension) kid -> core.height; 3337 3338 } else 3339 (void) XtQueryGeometry( kid, NULL, desired ); 3340 3341 3342 return; 3343 3344 } /* KidsPreferredGeometry */ 3345 3346 3347 /*----------------------------------------------------------------------*/ 3348 3349 static void MenuItemActivatedCB(Widget pb,XtCallbackProc action,XmAnyCallbackStruct * call_data)3350 MenuItemActivatedCB( Widget pb, 3351 XtCallbackProc action, 3352 XmAnyCallbackStruct *call_data ) 3353 { 3354 /* Variables. */ 3355 Arg args[ 5 ]; 3356 XmUbTimeBoxCallbackStruct cb; 3357 Cardinal n; 3358 Boolean range = True; 3359 XmUbTimeBoxWidget tbox; 3360 3361 /* Code. */ 3362 3363 /* The time box widget id is in user data. */ 3364 n = 0; 3365 XtSetArg( args[ n ], XmNuserData, &tbox ); n++; 3366 XtGetValues( pb, args, n ); 3367 3368 /* What to do depends on the selected action. */ 3369 switch((intptr_t)action){ 3370 3371 case (intptr_t) XmUbTB_ACTION_THIS_WEEK: 3372 FillInStartOfWeek( tbox ); 3373 AddDateWeek( tbox, 1, 1 ); 3374 break; 3375 3376 case (intptr_t) XmUbTB_ACTION_THIS_MONTH: 3377 FillInStartOfMonth( tbox ); 3378 AddDateMonth( tbox, 1, 1 ); 3379 break; 3380 3381 case (intptr_t) XmUbTB_ACTION_PLUS_ONE_HOUR: 3382 AddDateHour( tbox, 1 ); 3383 break; 3384 3385 case (intptr_t) XmUbTB_ACTION_PLUS_TWO_HOURS: 3386 AddDateHour( tbox, 2 ); 3387 break; 3388 3389 case (intptr_t) XmUbTB_ACTION_PLUS_ONE_WEEK: 3390 AddDateWeek( tbox, 1, 0 ); 3391 break; 3392 3393 case (intptr_t) XmUbTB_ACTION_PLUS_TWO_WEEKS: 3394 AddDateWeek( tbox, 2, 0 ); 3395 break; 3396 3397 case (intptr_t) XmUbTB_ACTION_PLUS_ONE_MONTH: 3398 AddDateMonth( tbox, 1, 0 ); 3399 break; 3400 3401 case (intptr_t) XmUbTB_ACTION_TIME_NOW: 3402 (void) XmUbTimeBoxSetStartTime( (Widget) tbox, 3403 TimLocalTime( TimMakeTimeNow() ) ); 3404 range = False; 3405 break; 3406 3407 case (intptr_t) XmUbTB_ACTION_DATE_NOW: 3408 (void) XmUbTimeBoxSetStartDate( (Widget) tbox, 3409 TimLocalTime( TimMakeTimeNow() ) ); 3410 range = False; 3411 break; 3412 3413 case (intptr_t) XmUbTB_ACTION_NOW: 3414 (void) XmUbTimeBoxSetStartDate( (Widget) tbox, 3415 TimLocalTime( TimMakeTimeNow() ) ); 3416 (void) XmUbTimeBoxSetStartTime( (Widget) tbox, 3417 TimLocalTime( TimMakeTimeNow() ) ); 3418 range = False; 3419 3420 break; 3421 3422 default: 3423 return; 3424 3425 } /* switch */ 3426 3427 /* Set the keyboard focus to the most recently inserted text. */ 3428 switch( (intptr_t) action ){ 3429 3430 case (intptr_t) XmUbTB_ACTION_TIME_NOW: 3431 /* Set keyboard focus to the start time field. */ 3432 if( tbox -> tbox.internal_children[ XmUbTB_CHILD_START_TIME ] != NULL ) 3433 XmProcessTraversal( 3434 tbox -> tbox.internal_children[ XmUbTB_CHILD_START_TIME ], 3435 XmTRAVERSE_CURRENT ); 3436 3437 break; 3438 3439 case (intptr_t) XmUbTB_ACTION_DATE_NOW: 3440 /* Set keyboard focus to the start date field. */ 3441 if( tbox -> tbox.internal_children[ XmUbTB_CHILD_START_DATE ] != NULL ) 3442 XmProcessTraversal( 3443 tbox -> tbox.internal_children[ XmUbTB_CHILD_START_DATE ], 3444 XmTRAVERSE_CURRENT ); 3445 3446 break; 3447 3448 case (intptr_t) XmUbTB_ACTION_NOW: 3449 /* Set keyboard focus to the start time or date field. */ 3450 if( tbox -> tbox.internal_children[ XmUbTB_CHILD_START_TIME ] != NULL ) 3451 XmProcessTraversal( 3452 tbox -> tbox.internal_children[ XmUbTB_CHILD_START_TIME ], 3453 XmTRAVERSE_CURRENT ); 3454 else if( 3455 tbox -> tbox.internal_children[ XmUbTB_CHILD_START_DATE ] != NULL ) 3456 XmProcessTraversal( 3457 tbox -> tbox.internal_children[ XmUbTB_CHILD_START_DATE ], 3458 XmTRAVERSE_CURRENT ); 3459 3460 break; 3461 3462 default: 3463 /* Set keyboard focus to the end time or date field. */ 3464 if( tbox -> tbox.internal_children[ XmUbTB_CHILD_END_TIME ] != NULL ) 3465 XmProcessTraversal( 3466 tbox -> tbox.internal_children[ XmUbTB_CHILD_END_TIME ], 3467 XmTRAVERSE_CURRENT ); 3468 else if( 3469 tbox -> tbox.internal_children[ XmUbTB_CHILD_END_DATE ] != NULL ) 3470 XmProcessTraversal( 3471 tbox -> tbox.internal_children[ XmUbTB_CHILD_END_DATE ], 3472 XmTRAVERSE_CURRENT ); 3473 3474 break; 3475 3476 } /* switch */ 3477 3478 /* A default action was selected. Invoke activate callbacks. */ 3479 if( tbox -> tbox.activate_callback != NULL ){ 3480 3481 cb.reason = XmUbCR_DEFAULT_ACTION; 3482 cb.event = NULL; 3483 cb.child_index = 0; 3484 cb.child = NULL; 3485 cb.action = action; 3486 cb.range = range; 3487 3488 XtCallCallbackList( (Widget) tbox, tbox -> tbox.activate_callback, 3489 (XtPointer) &cb ); 3490 3491 } 3492 3493 3494 3495 return; 3496 3497 } /* MenuItemActivatedCB */ 3498 3499 3500 /*----------------------------------------------------------------------*/ 3501 3502 Widget MonthDisplayId(XmUbTimeBoxWidget tbox)3503 MonthDisplayId( XmUbTimeBoxWidget tbox ) 3504 { 3505 /* Variables. */ 3506 char *name_buffer; 3507 Widget md; 3508 String wname; 3509 3510 /* Code. */ 3511 3512 wname = XtName( (Widget)tbox ); 3513 3514 /* Get the id of the month display widget. */ 3515 name_buffer = XtMalloc( strlen( wname ) + 8 ); 3516 /* sprintf( name_buffer, "%sMd", wname, wname ); */ 3517 sprintf( name_buffer, "%sMd", wname ); 3518 3519 md = XtNameToWidget( tbox -> tbox.date_selection_popup, name_buffer ); 3520 3521 XtFree( name_buffer ); 3522 3523 3524 return( md ); 3525 3526 } /* MonthDisplayId */ 3527 3528 3529 /*----------------------------------------------------------------------*/ 3530 3531 static void Resize(Widget widget)3532 Resize( Widget widget ) 3533 { 3534 3535 XmUbTimeBoxWidget tbox; 3536 3537 /* Code. */ 3538 3539 tbox = (XmUbTimeBoxWidget) widget; 3540 3541 tbox -> tbox.resize_called = True; 3542 3543 /* The sizes or positions of the children do not depend on the 3544 time box widget size, so we don't need to recalculate anything. */ 3545 3546 3547 return; 3548 3549 } /* Resize */ 3550 3551 3552 /*----------------------------------------------------------------------*/ 3553 3554 static XtGeometryResult QueryGeometry(Widget widget,XtWidgetGeometry * proposed,XtWidgetGeometry * answer)3555 QueryGeometry( Widget widget, 3556 XtWidgetGeometry *proposed, 3557 XtWidgetGeometry *answer ) 3558 { 3559 3560 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 3561 Dimension pref_height; 3562 Dimension pref_width; 3563 XmUbTimeBoxWidget tbox; 3564 3565 /* Code. */ 3566 3567 3568 tbox = (XmUbTimeBoxWidget) widget; 3569 3570 /* Get dimensions that we *really* want. */ 3571 GetChildPrefSizes( tbox, NULL, NULL, kids_sizes ); 3572 PrepareLayout( tbox, kids_sizes, &pref_width, &pref_height ); 3573 3574 answer -> request_mode = CWWidth | CWHeight; 3575 answer -> width = pref_width; 3576 answer -> height = pref_height; 3577 3578 3579 if( proposed == NULL ){ 3580 /* This is a query for the requested geometry. */ 3581 3582 if(( answer -> height == (int) tbox -> core.height ) && 3583 ( answer -> width == (int) tbox -> core.width )) 3584 return XtGeometryNo; 3585 else 3586 return XtGeometryAlmost; 3587 } 3588 3589 3590 /* The parent supplied a geometry suggestion. */ 3591 if(( answer -> height == proposed -> height ) && 3592 ( answer -> width == proposed -> width )) 3593 return XtGeometryYes; 3594 3595 if( ( proposed -> height <= 1 ) || 3596 ( proposed -> width <= 1 ) ) 3597 /* That's too small ! */ 3598 return XtGeometryNo; 3599 3600 3601 /* Only a compromise left. */ 3602 return XtGeometryAlmost; 3603 3604 } /* QueryGeometry */ 3605 3606 3607 /*----------------------------------------------------------------------*/ 3608 3609 static void PopdownDateSelectionDialogCB(Widget md,XmUbTimeBoxWidget tbox,XmAnyCallbackStruct * call_data)3610 PopdownDateSelectionDialogCB( Widget md, 3611 XmUbTimeBoxWidget tbox, 3612 XmAnyCallbackStruct *call_data ) 3613 { 3614 /* Code. */ 3615 3616 if( tbox -> tbox.destroy_dialogs ){ 3617 XtDestroyWidget( XtParent( tbox -> tbox.date_selection_popup ) ); 3618 tbox -> tbox.date_selection_popup = NULL; 3619 3620 } else 3621 XtUnmanageChild( tbox -> tbox.date_selection_popup ); 3622 3623 3624 return; 3625 3626 } /* PopdownDateSelectionDialogCB */ 3627 3628 3629 /*----------------------------------------------------------------------*/ 3630 3631 static void PopdownTimeSelectionDialogCB(Widget tw,XmUbTimeBoxWidget tbox,XmAnyCallbackStruct * call_data)3632 PopdownTimeSelectionDialogCB( Widget tw, 3633 XmUbTimeBoxWidget tbox, 3634 XmAnyCallbackStruct *call_data ) 3635 { 3636 /* Code. */ 3637 3638 if( tbox -> tbox.destroy_dialogs ){ 3639 XtDestroyWidget( XtParent( tbox -> tbox.time_selection_popup ) ); 3640 tbox -> tbox.time_selection_popup = NULL; 3641 3642 } else 3643 XtUnmanageChild( tbox -> tbox.time_selection_popup ); 3644 3645 3646 return; 3647 3648 } /* PopdownTimeSelectionDialogCB */ 3649 3650 3651 /*----------------------------------------------------------------------*/ 3652 3653 static void PopupDateSelection(Widget widget)3654 PopupDateSelection( Widget widget ) 3655 { 3656 /* Variables. */ 3657 XmUbTimeBoxStatus status; 3658 XmUbTimeBoxWidget tbox; 3659 time_t time; 3660 3661 /* Code. */ 3662 3663 /* We are called with the child. */ 3664 tbox = (XmUbTimeBoxWidget) XtParent( widget ); 3665 3666 /* If user callback, call it. */ 3667 if( tbox -> tbox.popup_selection_callback != NULL ){ 3668 CallDialogPopupCallback( tbox, widget, XmUbCR_POPUP_DATE_SELECTION ); 3669 3670 return; 3671 } 3672 3673 /* No callback is set and we should use our own dialog. */ 3674 if( tbox -> tbox.date_selection_popup == NULL ) 3675 CreateDateSelectionPopup( tbox ); 3676 3677 /* Set the index of the child that popped up the dialog. */ 3678 tbox -> tbox.field_for_date_selection = ChildIndex( tbox, widget ); 3679 3680 /* Pop up the dialog. */ 3681 3682 /* Set the current month first. */ 3683 switch( tbox -> tbox.field_for_date_selection ){ 3684 case XmUbTB_CHILD_START_DATE: 3685 status = XmUbTimeBoxGetStartDate( (Widget) tbox, &time ); 3686 break; 3687 3688 case XmUbTB_CHILD_END_DATE: 3689 status = XmUbTimeBoxGetEndDate( (Widget) tbox, &time ); 3690 3691 /* If no date is entered, try with the starting date as default. */ 3692 if( status != TBOX_OK ) 3693 status = XmUbTimeBoxGetStartDate( (Widget) tbox, &time ); 3694 break; 3695 3696 default: 3697 /* Can only be popped up from a date field. */ 3698 return; 3699 } 3700 3701 /* If no default date, use today. */ 3702 if( status != TBOX_OK ) 3703 time = TimLocalTime( TimMakeTimeNow() ); 3704 3705 XmUbMonthDisplaySetMonth( MonthDisplayId( tbox ), TimIndexOfYear( time ), 3706 TimIndexOfMonth( time ) ); 3707 3708 XtManageChild( tbox -> tbox.date_selection_popup ); 3709 3710 /* Set the focus to the current date. */ 3711 XmUbMonthDisplaySetFocusToDay( MonthDisplayId( tbox ), 3712 TimIndexOfDay( time ) ); 3713 3714 3715 return; 3716 3717 } /* PopupDateSelection */ 3718 3719 3720 /*----------------------------------------------------------------------*/ 3721 3722 static void PopupDateSelectionAction(Widget w,XEvent * event,String * params,Cardinal num_params)3723 PopupDateSelectionAction( Widget w, 3724 XEvent *event, 3725 String *params, 3726 Cardinal num_params ) 3727 { 3728 /* Variables. */ 3729 Widget parent; 3730 3731 /* Code. */ 3732 3733 parent = XtParent( w ); 3734 3735 (* ( (XmUbTimeBoxClassRec *) ( XtClass( parent ) ) ) -> 3736 timebox_class.popup_date_selection ) ( w ); 3737 3738 3739 return; 3740 3741 } /* PopupDateSelectionAction */ 3742 3743 3744 /*----------------------------------------------------------------------*/ 3745 3746 static void PopupTimeSelection(Widget widget)3747 PopupTimeSelection( Widget widget ) 3748 { 3749 /* Variables. */ 3750 XmUbTimeBoxStatus status; 3751 XmUbTimeBoxWidget tbox; 3752 Widget text_field; 3753 time_t time; 3754 3755 /* Code. */ 3756 3757 /* We are called with the child. */ 3758 tbox = (XmUbTimeBoxWidget) XtParent( widget ); 3759 3760 /* If user callback, call it. */ 3761 if( tbox -> tbox.popup_selection_callback != NULL ){ 3762 CallDialogPopupCallback( tbox, widget, XmUbCR_POPUP_TIME_SELECTION ); 3763 3764 return; 3765 } 3766 3767 /* No callback is set and we should use our own dialog. */ 3768 if( tbox -> tbox.time_selection_popup == NULL ) 3769 CreateTimeSelectionPopup( tbox ); 3770 3771 /* Set the index of the child that popped up the dialog. */ 3772 tbox -> tbox.field_for_time_selection = ChildIndex( tbox, widget ); 3773 3774 3775 /* Set the start time first. */ 3776 switch( tbox -> tbox.field_for_time_selection ){ 3777 case XmUbTB_CHILD_START_TIME: 3778 status = XmUbTimeBoxGetStartTime( (Widget) tbox, &time ); 3779 break; 3780 3781 case XmUbTB_CHILD_END_TIME: 3782 status = XmUbTimeBoxGetEndTime( (Widget) tbox, &time ); 3783 break; 3784 3785 default: 3786 /* Can only be popped up from a time field. */ 3787 return; 3788 3789 } 3790 3791 /* If we could get no default, use now. */ 3792 if( status != TBOX_OK ) 3793 time = TimLocalTime( TimMakeTimeNow() ); 3794 3795 XmUbTimeSliderSetTime( TimeSliderId( tbox ), time ); 3796 3797 XtManageChild( tbox -> tbox.time_selection_popup ); 3798 3799 /* Set keyboard focus to the text field. */ 3800 text_field = XmUbTimeSliderGetChild( TimeSliderId( tbox ), 3801 XmUbTS_CHILD_TEXT_FIELD ); 3802 if( text_field != NULL ) 3803 XmProcessTraversal( text_field, XmTRAVERSE_CURRENT ); 3804 3805 3806 return; 3807 3808 } /* PopupTimeSelection */ 3809 3810 3811 /*----------------------------------------------------------------------*/ 3812 3813 static void PopupTimeSelectionAction(Widget w,XEvent * event,String * params,Cardinal num_params)3814 PopupTimeSelectionAction( Widget w, 3815 XEvent *event, 3816 String *params, 3817 Cardinal num_params ) 3818 { 3819 /* Variables. */ 3820 Widget parent; 3821 3822 /* Code. */ 3823 3824 parent = XtParent( w ); 3825 3826 (* ( (XmUbTimeBoxClassRec *) ( XtClass( parent ) ) ) -> 3827 timebox_class.popup_time_selection ) ( w ); 3828 3829 3830 return; 3831 3832 } /* PopupTimeSelectionAction */ 3833 3834 3835 /*----------------------------------------------------------------------*/ 3836 3837 static void PrepareLayout(XmUbTimeBoxWidget tbox,KidDimensionRec sizes[],Dimension * own_width,Dimension * own_height)3838 PrepareLayout( XmUbTimeBoxWidget tbox, 3839 KidDimensionRec sizes[], 3840 Dimension *own_width, 3841 Dimension *own_height ) 3842 { 3843 /* Variables. */ 3844 int first_field; 3845 int index_of_first_field = 0; 3846 int index_of_last_field = 0; 3847 int last_field; 3848 int index; 3849 Dimension max_widget_height; 3850 Dimension max_widget_width; 3851 Position pos_offset; 3852 Dimension spacing; 3853 Position text_field_start; 3854 int use_field; 3855 3856 /* Code. */ 3857 3858 if( tbox -> tbox.menu_enabled && 3859 ( tbox -> tbox.menu_position == XmUbPOSITION_FIRST ) ){ 3860 /* The menu should be placed to the left of the first field. */ 3861 sizes[ XmUbTB_CHILD_MENU_BAR ].x = (Position) tbox -> tbox.margin_width; 3862 3863 text_field_start = sizes[ XmUbTB_CHILD_MENU_BAR ].x + 3864 (Position) sizes[ XmUbTB_CHILD_MENU_BAR ].width + 3865 (Position) tbox -> tbox.menu_spacing; 3866 3867 } else { 3868 /* Menu last or not at all. */ 3869 text_field_start = (Position) tbox -> tbox.margin_width; 3870 } 3871 3872 /* Position the text widgets. */ 3873 3874 switch( tbox -> tbox.widget_format ){ 3875 case XmUbTB_FORMAT_D: 3876 case XmUbTB_FORMAT_T: 3877 if( tbox -> tbox.widget_format == XmUbTB_FORMAT_D ) 3878 index = XmUbTB_CHILD_START_DATE; 3879 else 3880 index = XmUbTB_CHILD_START_TIME; 3881 3882 sizes[ index ].x = text_field_start; 3883 sizes[ index ].y = (Position) tbox -> tbox.margin_height; 3884 3885 *own_width = (Dimension) sizes[ index ].x + sizes[ index ].width + 3886 2 * tbox -> tbox.margin_width; 3887 *own_height = MAX( sizes[ XmUbTB_CHILD_MENU_BAR ].height, 3888 sizes[ index ].height ) + 3889 2 * tbox -> tbox.margin_height; 3890 3891 index_of_first_field = index; 3892 index_of_last_field = index; 3893 3894 break; 3895 3896 case XmUbTB_FORMAT_DT: 3897 case XmUbTB_FORMAT_DD: 3898 case XmUbTB_FORMAT_TT: 3899 3900 if( tbox -> tbox.widget_format == XmUbTB_FORMAT_DT ){ 3901 first_field = XmUbTB_CHILD_START_DATE; 3902 last_field = XmUbTB_CHILD_START_TIME; 3903 spacing = tbox -> tbox.field_spacing; 3904 3905 } else if( tbox -> tbox.widget_format == XmUbTB_FORMAT_DD ){ 3906 first_field = XmUbTB_CHILD_START_DATE; 3907 last_field = XmUbTB_CHILD_END_DATE; 3908 spacing = tbox -> tbox.range_spacing; 3909 3910 } else { 3911 first_field = XmUbTB_CHILD_START_TIME; 3912 last_field = XmUbTB_CHILD_END_TIME; 3913 spacing = tbox -> tbox.range_spacing; 3914 } 3915 3916 sizes[ first_field ].x = text_field_start; 3917 sizes[ first_field ].y = (Position) tbox -> tbox.margin_height; 3918 3919 if( ( tbox -> tbox.orientation == XmHORIZONTAL ) || 3920 ( ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DT ) && 3921 tbox -> tbox.component_together ) ){ 3922 /* Text fields should be ordered horizontally. */ 3923 sizes[ last_field ].x = sizes[ first_field ].x + 3924 (Position) sizes[ first_field ].width + (Position) spacing; 3925 3926 sizes[ last_field ].y = sizes[ first_field ].y; 3927 3928 *own_width = (Dimension) sizes[ last_field ].x + 3929 sizes[ last_field ].width + tbox -> tbox.margin_width; 3930 3931 *own_height = MAX( MAX( sizes[ first_field ].height, 3932 sizes[ last_field ].height ), 3933 sizes[ XmUbTB_CHILD_MENU_BAR ].height ) + 3934 2 * tbox -> tbox.margin_height; 3935 3936 } else { 3937 /* Text fields should be ordered vertically. */ 3938 3939 sizes[ last_field ].x = sizes[ first_field ].x; 3940 3941 sizes[ last_field ].y = sizes[ first_field ].y + 3942 (Position) sizes[ first_field ].height + (Position) spacing; 3943 3944 *own_width = (Dimension) sizes[ first_field ].x + 3945 MAX( sizes[ first_field ].width, sizes[ last_field ].width ) + 3946 tbox -> tbox.margin_width; 3947 3948 *own_height = (Dimension) sizes[ last_field ].y + 3949 sizes[ last_field ].height + tbox -> tbox.margin_height; 3950 } 3951 3952 index_of_first_field = first_field; 3953 index_of_last_field = last_field; 3954 3955 break; 3956 3957 case XmUbTB_FORMAT_DTDT: 3958 sizes[ XmUbTB_CHILD_START_DATE ].x = text_field_start; 3959 sizes[ XmUbTB_CHILD_START_DATE ].y = 3960 (Position) tbox -> tbox.margin_height; 3961 3962 if( tbox -> tbox.orientation == XmHORIZONTAL ){ 3963 /* Horizontal orientation. */ 3964 3965 sizes[ XmUbTB_CHILD_START_TIME ].x = 3966 sizes[ XmUbTB_CHILD_START_DATE ].x + 3967 (Position) sizes[ XmUbTB_CHILD_START_DATE ].width + 3968 (Position) tbox -> tbox.field_spacing; 3969 sizes[ XmUbTB_CHILD_START_TIME ].y = 3970 sizes[ XmUbTB_CHILD_START_DATE ].y; 3971 3972 sizes[ XmUbTB_CHILD_END_DATE ].x = 3973 sizes[ XmUbTB_CHILD_START_TIME ].x + 3974 (Position) sizes[ XmUbTB_CHILD_START_TIME ].width + 3975 (Position) tbox -> tbox.range_spacing; 3976 sizes[ XmUbTB_CHILD_END_DATE ].y = 3977 sizes[ XmUbTB_CHILD_START_DATE ].y; 3978 3979 sizes[ XmUbTB_CHILD_END_TIME ].x = 3980 sizes[ XmUbTB_CHILD_END_DATE ].x + 3981 (Position) sizes[ XmUbTB_CHILD_END_DATE ].width + 3982 (Position) tbox -> tbox.field_spacing; 3983 sizes[ XmUbTB_CHILD_END_TIME ].y = 3984 sizes[ XmUbTB_CHILD_START_DATE ].y; 3985 3986 max_widget_height = sizes[ XmUbTB_CHILD_MENU_BAR ].height; 3987 for( index = XmUbTB_CHILD_START_DATE; index < NO_INTERNAL_CHILDREN; 3988 index ++ ){ 3989 if( sizes[ index ].height > max_widget_height ) 3990 max_widget_height = sizes[ index ].height; 3991 } 3992 3993 *own_width = (Dimension) sizes[ XmUbTB_CHILD_END_TIME ].y + 3994 sizes[ XmUbTB_CHILD_END_TIME ].width + 3995 tbox -> tbox.margin_width; 3996 *own_height = max_widget_height + 2 * tbox -> tbox.margin_height; 3997 3998 } else if( tbox -> tbox.component_together ){ 3999 /* Place the text widgets in two rows. */ 4000 4001 sizes[ XmUbTB_CHILD_START_TIME ].x = 4002 sizes[ XmUbTB_CHILD_START_DATE ].x + 4003 (Position) sizes[ XmUbTB_CHILD_START_DATE ].width + 4004 (Position) tbox -> tbox.field_spacing; 4005 sizes[ XmUbTB_CHILD_START_TIME ].y = 4006 sizes[ XmUbTB_CHILD_START_DATE ].y; 4007 4008 sizes[ XmUbTB_CHILD_END_DATE ].x = sizes[ XmUbTB_CHILD_START_DATE ].x; 4009 sizes[ XmUbTB_CHILD_END_DATE ].y = sizes[ XmUbTB_CHILD_START_DATE ].y + 4010 (Position) sizes[ XmUbTB_CHILD_START_DATE ].height + 4011 (Position) tbox -> tbox.range_spacing; 4012 4013 sizes[ XmUbTB_CHILD_END_TIME ].x = sizes[ XmUbTB_CHILD_END_DATE ].x + 4014 (Position) sizes[ XmUbTB_CHILD_END_DATE ].width + 4015 (Position) tbox -> tbox.field_spacing; 4016 sizes[ XmUbTB_CHILD_END_TIME ].y = sizes[ XmUbTB_CHILD_END_DATE ].y; 4017 4018 *own_width = MAX( (Dimension) sizes[ XmUbTB_CHILD_START_TIME ].x + 4019 sizes[ XmUbTB_CHILD_START_TIME ].width, 4020 (Dimension) sizes[ XmUbTB_CHILD_END_TIME ].x + 4021 sizes[ XmUbTB_CHILD_END_TIME ].width ) + 4022 tbox -> tbox.margin_width; 4023 *own_height = (Dimension) sizes[ XmUbTB_CHILD_END_TIME ].y + 4024 MAX( sizes[ XmUbTB_CHILD_END_TIME ].height, 4025 sizes[ XmUbTB_CHILD_END_DATE ].height ) + 4026 tbox -> tbox.margin_height; 4027 4028 } else { 4029 /* Place all text fields under eachother. */ 4030 4031 sizes[ XmUbTB_CHILD_START_TIME ].x = 4032 sizes[ XmUbTB_CHILD_START_DATE ].x; 4033 sizes[ XmUbTB_CHILD_START_TIME ].y = 4034 sizes[ XmUbTB_CHILD_START_DATE ].y + 4035 (Position) sizes[ XmUbTB_CHILD_START_DATE ].height + 4036 (Position) tbox -> tbox.field_spacing; 4037 4038 sizes[ XmUbTB_CHILD_END_DATE ].x = 4039 sizes[ XmUbTB_CHILD_START_DATE ].x; 4040 sizes[ XmUbTB_CHILD_END_DATE ].y = 4041 sizes[ XmUbTB_CHILD_START_TIME ].y + 4042 (Position) sizes[ XmUbTB_CHILD_START_TIME ].height + 4043 (Position) tbox -> tbox.range_spacing; 4044 4045 sizes[ XmUbTB_CHILD_END_TIME ].x = 4046 sizes[ XmUbTB_CHILD_START_DATE ].x; 4047 sizes[ XmUbTB_CHILD_END_TIME ].y = 4048 sizes[ XmUbTB_CHILD_END_DATE ].y + 4049 (Position) sizes[ XmUbTB_CHILD_END_DATE ].height + 4050 (Position) tbox -> tbox.field_spacing; 4051 4052 max_widget_width = 0; 4053 for( index = XmUbTB_CHILD_START_DATE; index < NO_INTERNAL_CHILDREN; 4054 index ++ ){ 4055 if( sizes[ index ].width > max_widget_width ) 4056 max_widget_width = sizes[ index ].width; 4057 } 4058 4059 *own_width = (Dimension) sizes[ XmUbTB_CHILD_START_DATE ].x + 4060 max_widget_width + tbox -> tbox.margin_width; 4061 *own_height = (Dimension) sizes[ XmUbTB_CHILD_END_TIME ].y + 4062 sizes[ XmUbTB_CHILD_END_TIME ].height + 4063 tbox -> tbox.margin_height; 4064 } 4065 4066 index_of_first_field = XmUbTB_CHILD_START_DATE; 4067 index_of_last_field = XmUbTB_CHILD_END_TIME; 4068 4069 break; 4070 4071 case XmUbTB_FORMAT_DTT: 4072 sizes[ XmUbTB_CHILD_START_DATE ].x = text_field_start; 4073 sizes[ XmUbTB_CHILD_START_DATE ].y = 4074 (Position) tbox -> tbox.margin_height; 4075 4076 if( tbox -> tbox.orientation == XmHORIZONTAL ){ 4077 /* Lay out the text fields horizontally. */ 4078 sizes[ XmUbTB_CHILD_START_TIME ].x = 4079 sizes[ XmUbTB_CHILD_START_DATE ].x + 4080 (Position) sizes[ XmUbTB_CHILD_START_DATE ].width + 4081 (Position) tbox -> tbox.field_spacing; 4082 sizes[ XmUbTB_CHILD_START_TIME ].y = 4083 sizes[ XmUbTB_CHILD_START_DATE ].y; 4084 4085 sizes[ XmUbTB_CHILD_END_TIME ].x = sizes[ XmUbTB_CHILD_START_TIME ].x + 4086 (Position) sizes[ XmUbTB_CHILD_START_TIME ].width + 4087 (Position) tbox -> tbox.range_spacing; 4088 sizes[ XmUbTB_CHILD_END_TIME ].y = 4089 sizes[ XmUbTB_CHILD_START_DATE ].y; 4090 4091 max_widget_height = sizes[ XmUbTB_CHILD_MENU_BAR ].height; 4092 for( index = XmUbTB_CHILD_START_DATE; index < NO_INTERNAL_CHILDREN; 4093 index ++ ){ 4094 if( sizes[ index ].height > max_widget_height ) 4095 max_widget_height = sizes[ index ].height; 4096 } 4097 4098 *own_width = (Dimension) sizes[ XmUbTB_CHILD_END_TIME ].x + 4099 sizes[ XmUbTB_CHILD_END_TIME ].width + tbox -> tbox.margin_width; 4100 *own_height = max_widget_height + 2 * tbox -> tbox.margin_height; 4101 4102 } else if( tbox -> tbox.component_together ){ 4103 /* Place the text widgets in two rows. */ 4104 4105 sizes[ XmUbTB_CHILD_START_TIME ].x = 4106 sizes[ XmUbTB_CHILD_START_DATE ].x + 4107 (Position) sizes[ XmUbTB_CHILD_START_DATE ].width + 4108 (Position) tbox -> tbox.field_spacing; 4109 sizes[ XmUbTB_CHILD_START_TIME ].y = 4110 sizes[ XmUbTB_CHILD_START_DATE ].y; 4111 4112 sizes[ XmUbTB_CHILD_END_TIME ].x = sizes[ XmUbTB_CHILD_START_TIME ].x; 4113 sizes[ XmUbTB_CHILD_END_TIME ].y = sizes[ XmUbTB_CHILD_START_TIME ].y + 4114 (Position) sizes[ XmUbTB_CHILD_START_TIME ].height + 4115 (Position) tbox -> tbox.range_spacing; 4116 4117 *own_width = MAX( (Dimension) sizes[ XmUbTB_CHILD_START_TIME ].x + 4118 sizes[ XmUbTB_CHILD_START_TIME ].width, 4119 (Dimension) sizes[ XmUbTB_CHILD_END_TIME ].x + 4120 sizes[ XmUbTB_CHILD_END_TIME ].width ) + 4121 tbox -> tbox.margin_width; 4122 4123 *own_height = (Dimension) sizes[ XmUbTB_CHILD_END_TIME ].y + 4124 sizes[ XmUbTB_CHILD_END_TIME ].height + 4125 tbox -> tbox.margin_height; 4126 4127 } else { 4128 /* Lay out all text widgets vertically. */ 4129 4130 sizes[ XmUbTB_CHILD_START_TIME ].x = 4131 sizes[ XmUbTB_CHILD_START_DATE ].x; 4132 sizes[ XmUbTB_CHILD_START_TIME ].y = 4133 sizes[ XmUbTB_CHILD_START_DATE ].y + 4134 (Position) sizes[ XmUbTB_CHILD_START_DATE ].height + 4135 (Position) tbox -> tbox.field_spacing; 4136 4137 sizes[ XmUbTB_CHILD_END_TIME ].x = 4138 sizes[ XmUbTB_CHILD_START_DATE ].x; 4139 sizes[ XmUbTB_CHILD_END_TIME ].y = 4140 sizes[ XmUbTB_CHILD_START_TIME ].y + 4141 (Position) sizes[ XmUbTB_CHILD_START_TIME ].height + 4142 (Position) tbox -> tbox.range_spacing; 4143 4144 max_widget_width = 0; 4145 for( index = XmUbTB_CHILD_START_DATE; index < NO_INTERNAL_CHILDREN; 4146 index ++ ){ 4147 if( sizes[ index ].width > max_widget_width ) 4148 max_widget_width = sizes[ index ].width; 4149 } 4150 4151 *own_width = (Dimension) sizes[ XmUbTB_CHILD_START_DATE ].x + 4152 max_widget_width + tbox -> tbox.margin_width; 4153 *own_height = (Dimension) sizes[ XmUbTB_CHILD_END_TIME ].y + 4154 sizes[ XmUbTB_CHILD_END_TIME ].height + 4155 tbox -> tbox.margin_height; 4156 } 4157 4158 index_of_first_field = XmUbTB_CHILD_START_DATE; 4159 index_of_last_field = XmUbTB_CHILD_END_TIME; 4160 4161 break; 4162 } 4163 4164 /* If the menu button should be placed last, this is the time to do it. */ 4165 if( tbox -> tbox.menu_enabled ){ 4166 4167 if( tbox -> tbox.menu_position == XmUbPOSITION_FIRST ){ 4168 /* The menu has already been positioned horizontally. */ 4169 use_field = index_of_first_field; 4170 4171 } else { 4172 /* Position the menu after the last field. */ 4173 use_field = index_of_last_field; 4174 4175 sizes[ XmUbTB_CHILD_MENU_BAR ].x = sizes[ use_field ].x + 4176 (Position) ( sizes[ use_field ].width + tbox -> tbox.menu_spacing ); 4177 4178 *own_width += ( sizes[ XmUbTB_CHILD_MENU_BAR ].width + 4179 tbox -> tbox.menu_spacing ); 4180 } 4181 4182 /* Center the menu vertically with the adjacent field. */ 4183 4184 if( sizes[ use_field ].height > sizes[ XmUbTB_CHILD_MENU_BAR ].height ) 4185 pos_offset = (Position) ( sizes[ use_field ].height - 4186 sizes[ XmUbTB_CHILD_MENU_BAR ].height ) / 2; 4187 else 4188 pos_offset = - (Position) ( sizes[ XmUbTB_CHILD_MENU_BAR ].height - 4189 sizes[ use_field ].height ) / 2; 4190 4191 sizes[ XmUbTB_CHILD_MENU_BAR ].y = sizes[ use_field ].y + pos_offset; 4192 4193 } 4194 4195 /* Modify own height if menu button last. */ 4196 if( tbox -> tbox.menu_enabled && 4197 ( tbox -> tbox.menu_position == XmUbPOSITION_LAST ) ){ 4198 4199 *own_height = MAX( ( (Dimension) sizes[ XmUbTB_CHILD_MENU_BAR ].y + 4200 sizes[ XmUbTB_CHILD_MENU_BAR ].height ), 4201 ( (Dimension) sizes[ use_field ].y + 4202 sizes[ use_field ].height ) ) + 4203 tbox -> tbox.margin_height; 4204 } 4205 4206 4207 return; 4208 4209 } /* PrepareLayout */ 4210 4211 4212 /*----------------------------------------------------------------------*/ 4213 4214 static Boolean ResizeIfNeeded(XmUbTimeBoxWidget tbox,KidDimensionRec sizes[])4215 ResizeIfNeeded( XmUbTimeBoxWidget tbox, 4216 KidDimensionRec sizes[] ) 4217 { 4218 4219 /* Variables. */ 4220 Boolean layout_done; 4221 Dimension pref_height; 4222 Dimension pref_width; 4223 XtWidgetGeometry request; 4224 XtGeometryResult result; 4225 4226 /* Code. */ 4227 4228 /* Initialize. */ 4229 layout_done = False; 4230 4231 /* Get the preferred dimensions of the time box widget. */ 4232 GetChildPrefSizes( tbox, NULL, NULL, sizes ); 4233 PrepareLayout( tbox, sizes, &pref_width, &pref_height ); 4234 4235 /* If we want the same dimensions, no resizing is needed. */ 4236 if(( pref_width == tbox -> core.width ) && 4237 ( pref_height == tbox -> core.height )) 4238 return False; 4239 4240 /* Dimensions are different. Try to resize. */ 4241 request.request_mode = CWWidth | CWHeight; 4242 4243 request.width = pref_width; 4244 request.height = pref_height; 4245 4246 tbox -> tbox.resize_called = False; 4247 4248 do { 4249 4250 result = XtMakeGeometryRequest( (Widget) tbox, &request, &request ); 4251 4252 } while( result == XtGeometryAlmost ); 4253 4254 if( result == XtGeometryNo ) 4255 return False; 4256 4257 /* Resize done. Core fields have already been updated. */ 4258 return( tbox -> tbox.resize_called ); 4259 4260 } /* ResizeIfNeeded */ 4261 4262 4263 /*----------------------------------------------------------------------*/ 4264 4265 static void SelectAllTextCB(Widget tw,XmUbTimeBoxWidget tbox,XmAnyCallbackStruct * call_data)4266 SelectAllTextCB( Widget tw, 4267 XmUbTimeBoxWidget tbox, 4268 XmAnyCallbackStruct *call_data ) 4269 { 4270 /* Variables. */ 4271 XmTextPosition last; 4272 4273 /* Code. */ 4274 4275 /* Select all text in the text widget. */ 4276 4277 last = XmTextGetLastPosition( tw ); 4278 4279 if( last > 0 ) 4280 XmTextSetSelection( tw, 0, last, CurrentTime ); 4281 4282 /* Set the insertion position to the start of the widget. */ 4283 XmTextSetInsertionPosition( tw, 0 ); 4284 4285 4286 return; 4287 4288 } /* SelectAllTextCB */ 4289 4290 4291 /*----------------------------------------------------------------------*/ 4292 4293 XmUbTimeBoxStatus SetChildString(XmUbTimeBoxWidget tbox,int child,char * str)4294 SetChildString( XmUbTimeBoxWidget tbox, 4295 int child, 4296 char *str ) 4297 { 4298 /* Variables. */ 4299 Widget tw; 4300 4301 /* Code. */ 4302 4303 tw = tbox -> tbox.internal_children[ child ]; 4304 if( tw == NULL ) 4305 return( TBOX_NO_FIELD ); 4306 4307 XmTextSetString( tw, str ); 4308 4309 4310 return( TBOX_OK ); 4311 4312 } /* SetChildString */ 4313 4314 4315 /*----------------------------------------------------------------------*/ 4316 4317 static Boolean SetValues(Widget current,Widget request,Widget new,ArgList args,Cardinal * num_args)4318 SetValues( Widget current, 4319 Widget request, 4320 Widget new, 4321 ArgList args, 4322 Cardinal *num_args ) 4323 { 4324 #ifdef Differs 4325 #undef Differs 4326 #endif 4327 4328 #define Differs( field ) ( curW -> field != newW -> field ) 4329 4330 /* Variables. */ 4331 XmUbTimeBoxWidget curW; 4332 int index; 4333 Arg local_args[ 3 ]; 4334 Cardinal n; 4335 char *name_buffer; 4336 XmUbTimeBoxWidget newW; 4337 char *newstr; 4338 Boolean redisplay = False; 4339 char *str; 4340 Boolean visual_changed = False; 4341 Widget w; 4342 char *wname; 4343 XmString xm; 4344 4345 /* Code. */ 4346 4347 curW = (XmUbTimeBoxWidget) current; 4348 newW = (XmUbTimeBoxWidget) new; 4349 4350 /* Margins and spacings. */ 4351 if( Differs( tbox.field_spacing ) || 4352 Differs( tbox.menu_spacing ) || 4353 Differs( tbox.range_spacing ) || 4354 Differs( tbox.margin_width ) || 4355 Differs( tbox.margin_height ) ) 4356 visual_changed = True; 4357 4358 /* These changes should be propagated to the child widgets. */ 4359 if( Differs( core.background_pixel ) || 4360 Differs( manager.foreground ) ){ 4361 4362 n = 0; 4363 4364 if( Differs( core.background_pixel ) ){ 4365 XtSetArg( local_args[ n ], XmNbackground, 4366 newW -> core.background_pixel ); n++; 4367 } 4368 if( Differs( manager.foreground ) ){ 4369 XtSetArg( local_args[ n ], XmNforeground, 4370 newW -> manager.foreground ); n++; 4371 } 4372 4373 /* Set the change for all child widgets. */ 4374 for( index = 0; index < NO_INTERNAL_CHILDREN; index ++ ) 4375 XtSetValues( newW -> tbox.internal_children[ index ], local_args, n ); 4376 4377 redisplay = True; 4378 } 4379 4380 /* Changes affecting the time selection dialog. */ 4381 4382 if( Differs( tbox.ok_label ) ){ 4383 4384 if( curW -> tbox.ok_label != NULL ) 4385 XmStringFree( curW -> tbox.ok_label ); 4386 4387 /* Copy the XmStrings and set new resources for dialog. */ 4388 if( newW -> tbox.ok_label != NULL ){ 4389 xm = XmStringCopy( newW -> tbox.ok_label ); 4390 newW -> tbox.ok_label = xm; 4391 } 4392 4393 if( newW -> tbox.time_selection_popup != NULL ){ 4394 /* We need the Ok button. */ 4395 wname = XtName( (Widget)newW ); 4396 name_buffer = XtMalloc( strlen( wname ) + 6 ); 4397 sprintf( name_buffer, "%sTok", wname ); 4398 4399 w = XtNameToWidget( newW -> tbox.time_selection_popup, name_buffer ); 4400 4401 if( w != NULL ){ 4402 n = 0; 4403 XtSetArg( local_args[ n ], XmNlabelString, 4404 newW -> tbox.ok_label ); n++; 4405 XtSetValues( w, local_args, n ); 4406 } else 4407 printf( "Error in XtNameToWidget, ok button is NULL.\n" ); 4408 } 4409 } 4410 4411 if( Differs( tbox.cancel_label ) ){ 4412 4413 if( curW -> tbox.cancel_label != NULL ) 4414 XmStringFree( curW -> tbox.cancel_label ); 4415 4416 /* Copy the XmStrings and set new resources for dialog. */ 4417 if( newW -> tbox.cancel_label != NULL ){ 4418 xm = XmStringCopy( newW -> tbox.cancel_label ); 4419 newW -> tbox.cancel_label = xm; 4420 } 4421 4422 if( newW -> tbox.time_selection_popup != NULL ){ 4423 /* We need the Ok button. */ 4424 wname = XtName( (Widget)newW ); 4425 name_buffer = XtMalloc( strlen( wname ) + 6 ); 4426 sprintf( name_buffer, "%sTcan", wname ); 4427 4428 w = XtNameToWidget( newW -> tbox.time_selection_popup, name_buffer ); 4429 4430 if( w != NULL ){ 4431 n = 0; 4432 XtSetArg( local_args[ n ], XmNlabelString, 4433 newW -> tbox.cancel_label ); n++; 4434 XtSetValues( w, local_args, n ); 4435 } else 4436 printf( "Error in XtNameToWidget, cancel button is NULL.\n" ); 4437 } 4438 } 4439 4440 /* Changes affecting the time selection dialog shell. */ 4441 if( Differs( tbox.time_selection_title ) ){ 4442 4443 if( curW -> tbox.time_selection_title != NULL ) 4444 XtFree( curW -> tbox.time_selection_title ); 4445 4446 if( newW -> tbox.time_selection_title != NULL ){ 4447 str = XtMalloc( strlen( newW -> tbox.time_selection_title ) + 1 ); 4448 strcpy( str, newW -> tbox.time_selection_title ); 4449 newW -> tbox.time_selection_title = str; 4450 } 4451 4452 if( newW -> tbox.time_selection_popup != NULL ){ 4453 n = 0; 4454 XtSetArg( local_args[ n ], XmNtitle, 4455 newW -> tbox.time_selection_title ); n++; 4456 XtSetValues( XtParent( newW -> tbox.time_selection_popup ), 4457 local_args, n ); 4458 } 4459 } 4460 4461 /* Changes affecting the date selection dialog shell. */ 4462 if( Differs( tbox.date_selection_title ) ){ 4463 4464 if( curW -> tbox.date_selection_title != NULL ) 4465 XtFree( curW -> tbox.date_selection_title ); 4466 4467 if( newW -> tbox.date_selection_title != NULL ){ 4468 str = XtMalloc( strlen( newW -> tbox.date_selection_title ) + 1 ); 4469 strcpy( str, newW -> tbox.date_selection_title ); 4470 newW -> tbox.date_selection_title = str; 4471 } 4472 4473 if( newW -> tbox.date_selection_popup != NULL ){ 4474 n = 0; 4475 XtSetArg( local_args[ n ], XmNtitle, 4476 newW -> tbox.date_selection_title ); n++; 4477 XtSetValues( XtParent( newW -> tbox.date_selection_popup ), 4478 local_args, n ); 4479 } 4480 } 4481 4482 4483 /* Changes affecting the month display dialog. */ 4484 if( Differs( tbox.week_label ) || 4485 Differs( tbox.month_label ) || 4486 Differs( tbox.year_label ) ){ 4487 4488 n = 0; 4489 4490 if( Differs( tbox.week_label ) ){ 4491 4492 if( curW -> tbox.week_label != NULL ) 4493 XmStringFree( curW -> tbox.week_label ); 4494 4495 if( newW -> tbox.week_label != NULL ){ 4496 xm = XmStringCopy( newW -> tbox.week_label ); 4497 newW -> tbox.week_label = xm; 4498 } 4499 4500 XtSetArg( local_args[ n ], XmUbNmdiWeekLabel, 4501 newW -> tbox.week_label ); n++; 4502 } 4503 4504 if( Differs( tbox.month_label ) ){ 4505 4506 if( curW -> tbox.month_label != NULL ) 4507 XmStringFree( curW -> tbox.week_label ); 4508 4509 if( newW -> tbox.month_label != NULL ){ 4510 xm = XmStringCopy( newW -> tbox.month_label ); 4511 newW -> tbox.month_label = xm; 4512 } 4513 4514 XtSetArg( local_args[ n ], XmUbNmdiMonthLabel, 4515 newW -> tbox.month_label ); n++; 4516 } 4517 4518 if( Differs( tbox.year_label ) ){ 4519 4520 if( curW -> tbox.year_label != NULL ) 4521 XmStringFree( curW -> tbox.week_label ); 4522 4523 if( newW -> tbox.year_label != NULL ){ 4524 xm = XmStringCopy( newW -> tbox.year_label ); 4525 newW -> tbox.year_label = xm; 4526 } 4527 4528 XtSetArg( local_args[ n ], XmUbNmdiYearLabel, 4529 newW -> tbox.year_label ); n++; 4530 } 4531 4532 if( newW -> tbox.date_selection_popup != NULL ) 4533 XtSetValues( newW -> tbox.date_selection_popup, local_args, n ); 4534 } 4535 4536 4537 4538 /* These resources may only be set at creation. */ 4539 if( Differs( tbox.component_together ) ){ 4540 WarningNoResourceChange( newW, "XmUbNtboxComponentTogether" ); 4541 newW -> tbox.component_together = curW -> tbox.component_together; 4542 } 4543 4544 if( Differs( tbox.destroy_dialogs ) ){ 4545 WarningNoResourceChange( newW, "XmUbNtboxDestroyDialogs" ); 4546 newW -> tbox.destroy_dialogs = curW -> tbox.destroy_dialogs; 4547 } 4548 4549 if( Differs( tbox.menu_enabled ) ){ 4550 WarningNoResourceChange( newW, "XmUbNtboxMenuEnabled" ); 4551 newW -> tbox.menu_enabled = curW -> tbox.menu_enabled; 4552 } 4553 4554 if( Differs( tbox.menu_items ) ){ 4555 WarningNoResourceChange( newW, "XmUbNtboxMenuItems" ); 4556 newW -> tbox.menu_items = curW -> tbox.menu_items; 4557 } 4558 4559 if( Differs( tbox.menu_label ) ){ 4560 WarningNoResourceChange( newW, "XmUbNtboxMenuLabel" ); 4561 newW -> tbox.menu_label = curW -> tbox.menu_label; 4562 } 4563 4564 if( Differs( tbox.menu_pixmap ) ){ 4565 WarningNoResourceChange( newW, "XmUbNtboxMenuPixmap" ); 4566 newW -> tbox.menu_pixmap = curW -> tbox.menu_pixmap; 4567 } 4568 4569 if( Differs( tbox.menu_position ) ){ 4570 WarningNoResourceChange( newW, "XmUbNtboxMenuPosition" ); 4571 newW -> tbox.menu_position = curW -> tbox.menu_position; 4572 } 4573 4574 if( Differs( tbox.num_menu_items ) ){ 4575 WarningNoResourceChange( newW, "XmUbNtboxNumMenuItems" ); 4576 newW -> tbox.num_menu_items = curW -> tbox.num_menu_items; 4577 } 4578 4579 if( Differs( tbox.orientation ) ){ 4580 WarningNoResourceChange( newW, "XmNorientation" ); 4581 newW -> tbox.orientation = curW -> tbox.orientation; 4582 } 4583 4584 if( Differs( tbox.widget_format ) ){ 4585 WarningNoResourceChange( newW, "XmUbNtboxFormat" ); 4586 newW -> tbox.widget_format = curW -> tbox.widget_format; 4587 } 4588 4589 /* Copy strings for scanning. */ 4590 #define SetMarker( field, default ) \ 4591 { \ 4592 if( curW -> field != newW -> field ){ \ 4593 if( curW -> field != NULL ) \ 4594 XtFree( curW -> field ); \ 4595 if( newW -> field == NULL ){ \ 4596 newstr = XtMalloc( strlen( default ) ); \ 4597 strcpy( newstr, default ); \ 4598 newW -> field = newstr; \ 4599 } else { \ 4600 newstr = XtMalloc( strlen( newW -> field ) ); \ 4601 strcpy( newstr, newW -> field ); \ 4602 newW -> field = newstr; \ 4603 } \ 4604 } \ 4605 } 4606 4607 SetMarker( tbox.day_marker, default_day_marker ); 4608 SetMarker( tbox.hour_marker, default_hour_marker ); 4609 SetMarker( tbox.minute_marker, default_minute_marker ); 4610 SetMarker( tbox.month_marker, default_month_marker ); 4611 SetMarker( tbox.week_marker, default_week_marker ); 4612 SetMarker( tbox.year_marker, default_year_marker ); 4613 4614 #undef SetMarker 4615 4616 if( visual_changed ){ 4617 4618 KidDimensionRec kids_sizes[ NO_INTERNAL_CHILDREN ]; 4619 Boolean resized; 4620 4621 /* Code. */ 4622 4623 resized = ResizeIfNeeded( newW, kids_sizes ); 4624 if( resized ) 4625 DoLayout( newW, NULL, NULL, kids_sizes ); 4626 4627 } 4628 4629 return( redisplay || visual_changed ); 4630 4631 #undef Differs 4632 4633 } /* SetValues */ 4634 4635 4636 /*----------------------------------------------------------------------*/ 4637 4638 static void TimeCompletionCB(Widget tw,XmUbTimeBoxWidget tbox,XmTextVerifyCallbackStruct * call_data)4639 TimeCompletionCB( Widget tw, 4640 XmUbTimeBoxWidget tbox, 4641 XmTextVerifyCallbackStruct *call_data ) 4642 { 4643 /* Variables. */ 4644 int child_index; 4645 Boolean restart; 4646 XmUbTimeBoxStatus status; 4647 4648 /* Code. */ 4649 4650 TimeCompletionCB_START: 4651 4652 /* Find child index for this field. */ 4653 child_index = ChildIndex( tbox, tw ); 4654 4655 /* Completion is different depending on which field we are dealing with. */ 4656 switch( child_index ){ 4657 4658 case XmUbTB_CHILD_START_TIME: 4659 status = CompleteStartTime( tbox ); 4660 break; 4661 4662 4663 case XmUbTB_CHILD_END_TIME: 4664 status = CompleteEndTime( tbox ); 4665 break; 4666 4667 default: 4668 /* This should not happen. */ 4669 printf( "TimeCompletionCB ERROR, called for wrong child.\n" ); 4670 return; 4671 4672 } /* switch */ 4673 4674 /* If there was an error, take care of it. May lead to restart. */ 4675 restart = TimeCompletionCallback( tw, child_index, tbox, 4676 (XmAnyCallbackStruct *) call_data, 4677 status ); 4678 if( restart ) 4679 goto TimeCompletionCB_START; 4680 4681 4682 return; 4683 4684 } /* TimeCompletionCB */ 4685 4686 4687 /*----------------------------------------------------------------------*/ 4688 4689 static Boolean TimeCompletionCallback(Widget tw,int child_index,XmUbTimeBoxWidget tbox,XmAnyCallbackStruct * call_data,XmUbTimeBoxStatus reason)4690 TimeCompletionCallback( Widget tw, 4691 int child_index, 4692 XmUbTimeBoxWidget tbox, 4693 XmAnyCallbackStruct *call_data, 4694 XmUbTimeBoxStatus reason ) 4695 { 4696 /* Variables. */ 4697 XmUbTimeBoxCallbackStruct callback_struct; 4698 char *str; 4699 4700 /* Code. */ 4701 4702 /* Initialize. Needed also if no callback. */ 4703 callback_struct.child_index = child_index; 4704 callback_struct.child = tw; 4705 callback_struct.restart_completion = False; 4706 4707 if( tbox -> tbox.completion_callback != NULL ){ 4708 4709 /* Common fields. */ 4710 if( call_data == NULL ) 4711 callback_struct.event = NULL; 4712 else 4713 callback_struct.event = call_data -> event; 4714 4715 switch( reason ){ 4716 4717 case TBOX_OK: 4718 callback_struct.reason = XmUbCR_COMPLETION_SUCCESS; 4719 break; 4720 4721 case TBOX_EMPTY: 4722 callback_struct.reason = XmUbCR_COMPLETION_EMPTY; 4723 break; 4724 4725 case TBOX_NO_COMPLETION: 4726 callback_struct.reason = XmUbCR_COMPLETION_FAILED; 4727 break; 4728 4729 default: 4730 break; 4731 } 4732 4733 XtCallCallbackList( (Widget) tbox, 4734 tbox -> tbox.completion_callback, 4735 (XtPointer) &callback_struct ); 4736 4737 } else { 4738 4739 /* No callback was defined. */ 4740 4741 /* If completion failed, we should indicate this. */ 4742 if( reason == TBOX_NO_COMPLETION ){ 4743 /* Don't flicker the string if it is already set. */ 4744 str = XmTextGetString( tw ); 4745 4746 if( strcmp( str, default_completion_failed_string ) != 0 ) 4747 XmTextSetString( tw, default_completion_failed_string ); 4748 4749 XtFree( str ); 4750 } 4751 } 4752 4753 4754 return( callback_struct.restart_completion ); 4755 4756 } /* TimeCompletionCallback */ 4757 4758 4759 /*----------------------------------------------------------------------*/ 4760 4761 static void TimeSelectedInDialogCB(Widget tw,XmUbTimeBoxWidget tbox,XmAnyCallbackStruct * call_data)4762 TimeSelectedInDialogCB( Widget tw, 4763 XmUbTimeBoxWidget tbox, 4764 XmAnyCallbackStruct *call_data ) 4765 { 4766 /* Variables. */ 4767 XmUbTimeBoxCallbackStruct cb; 4768 Boolean known_field = True; 4769 Widget slider; 4770 char *str; 4771 4772 /* Code. */ 4773 4774 /* Get the id of the slider widget. */ 4775 slider = TimeSliderId( tbox ); 4776 4777 if( slider == NULL ) 4778 printf( "Error in XtNameToWidget call, slider is NULL.\n" ); 4779 4780 /* Get the selected time. */ 4781 str = XmUbTimeSliderGetTimeString( (Widget) slider ); 4782 4783 /* Set the time in the box. */ 4784 switch( tbox -> tbox.field_for_time_selection ){ 4785 case XmUbTB_CHILD_START_TIME: 4786 XmUbTimeBoxSetStartTimeString( (Widget) tbox, str ); 4787 break; 4788 4789 case XmUbTB_CHILD_END_TIME: 4790 XmUbTimeBoxSetEndTimeString( (Widget) tbox, str ); 4791 break; 4792 4793 default: 4794 /* Not a recognized field. */ 4795 known_field = False; 4796 break; 4797 } 4798 4799 /* Get rid of the dialog. */ 4800 PopdownTimeSelectionDialogCB( tw, tbox, (XmAnyCallbackStruct *) call_data ); 4801 4802 4803 /* Cleanup. */ 4804 XtFree( str ); 4805 4806 /* Call activate callback. */ 4807 if( known_field && ( tbox -> tbox.activate_callback != NULL ) ){ 4808 4809 /* Set up callback structure. */ 4810 4811 cb.reason = XmUbCR_TIME_PICKED; 4812 cb.event = NULL; 4813 cb.child_index = tbox -> tbox.field_for_time_selection; 4814 cb.child = tbox -> tbox.internal_children[ cb.child_index ]; 4815 4816 XtCallCallbackList( (Widget) tbox, tbox -> tbox.activate_callback, 4817 (XtPointer) &cb ); 4818 } 4819 4820 4821 return; 4822 4823 } /* TimeSelectedInDialogCB */ 4824 4825 4826 /*----------------------------------------------------------------------*/ 4827 4828 Widget TimeSliderId(XmUbTimeBoxWidget tbox)4829 TimeSliderId( XmUbTimeBoxWidget tbox ) 4830 { 4831 /* Variables. */ 4832 char *name_buffer; 4833 Widget slider; 4834 String wname; 4835 4836 /* Code. */ 4837 4838 wname = XtName( (Widget)tbox ); 4839 4840 /* Get the id of the slider widget. */ 4841 name_buffer = XtMalloc( strlen( wname ) * 2 + 8 ); 4842 sprintf( name_buffer, "%sTs", wname ); 4843 4844 slider = XtNameToWidget( tbox -> tbox.time_selection_popup, name_buffer ); 4845 4846 XtFree( name_buffer ); 4847 4848 4849 return( slider ); 4850 4851 } /* TimeSliderId */ 4852 4853 4854 /*----------------------------------------------------------------------*/ 4855 4856 #if XmVersion > 1001 4857 4858 static void TransferDateField(Widget w,XtPointer closure,Atom * seltype,Atom * type,XtPointer value,unsigned long * length,int format)4859 TransferDateField( Widget w, 4860 XtPointer closure, 4861 Atom *seltype, 4862 Atom *type, 4863 XtPointer value, 4864 unsigned long *length, 4865 int format ) 4866 { 4867 /* Variables. */ 4868 char buffer[ TIME_STRING_BUFFER_LEN ]; 4869 XmUbTimeBoxCallbackStruct cb; 4870 Atom compound_text_atom; 4871 Atom date_transfer_atom; 4872 Boolean ok; 4873 XmTextPosition pos; 4874 Boolean range_transfer = False; 4875 char *str; 4876 XmUbTimeBoxWidget tbox; 4877 TIM_TIME_REF time; 4878 XmUbDateTransferRef transfer_data; 4879 Widget tw; 4880 XmString xm; 4881 4882 /* Code. */ 4883 4884 compound_text_atom = XmInternAtom( XtDisplay( w ), "COMPOUND_TEXT", False ); 4885 date_transfer_atom = XmInternAtom( XtDisplay( w ), XmUbDATE_TRANSFER, 4886 False ); 4887 4888 /* The text widget is passed in the parameter closure. */ 4889 tw = (Widget) closure; 4890 tbox = (XmUbTimeBoxWidget) XtParent( tw ); 4891 4892 if( *type == date_transfer_atom ){ 4893 /* We are being passed a structure with date information. 4894 Construct a string with the date in the local format. */ 4895 4896 /* Convert the first date, regardless of the type. */ 4897 transfer_data = (XmUbDateTransferRef) value; 4898 4899 time = TimMakeTime( transfer_data -> year, transfer_data -> month, 4900 transfer_data -> day, 0, 0, 0 ); 4901 ConvertToDateString( tbox, time, buffer, TIME_STRING_BUFFER_LEN - 1 ); 4902 4903 if( transfer_data -> type == XmUbTRANSFER_DATE ){ 4904 4905 /* Replace the text with the new date. */ 4906 XmTextSetString( tw, buffer ); 4907 4908 } else { 4909 4910 /* This is a range transfer. Set the start date. */ 4911 (void) XmUbTimeBoxSetStartDateString( (Widget) tbox, buffer ); 4912 4913 /* Convert end of range. */ 4914 if( ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DD ) || 4915 ( tbox -> tbox.widget_format == XmUbTB_FORMAT_DTDT ) ){ 4916 4917 time = TimMakeTime( transfer_data -> end_year, 4918 transfer_data -> end_month, 4919 transfer_data -> end_day, 0, 0, 0 ); 4920 ConvertToDateString( tbox, time, buffer, TIME_STRING_BUFFER_LEN - 1 ); 4921 4922 (void) XmUbTimeBoxSetEndDateString( (Widget) tbox, buffer ); 4923 4924 range_transfer = True; 4925 4926 } 4927 } 4928 4929 4930 /* Call the activate callback. */ 4931 if( tbox -> tbox.activate_callback != NULL ){ 4932 4933 cb.reason = XmUbCR_DATE_DROPPED; 4934 cb.event = NULL; 4935 cb.child_index = ChildIndex( tbox, tw ); 4936 cb.child = tw; 4937 cb.range = range_transfer; 4938 4939 XtCallCallbackList( (Widget) tbox, tbox -> tbox.activate_callback, 4940 (XtPointer) &cb ); 4941 } 4942 4943 4944 } else if( *type == compound_text_atom ){ 4945 /* We are getting compound text. Need to convert it to normal string. */ 4946 xm = XmCvtCTToXmString( value ); 4947 ok = XmStringGetLtoR( xm, XmSTRING_DEFAULT_CHARSET, &str ); 4948 4949 /* Insert the string at the current position. */ 4950 if( ok ){ 4951 4952 pos = XmTextGetInsertionPosition( tw ); 4953 XmTextInsert( tw, pos, str ); 4954 4955 XtFree( str ); 4956 } 4957 4958 XmStringFree( xm ); 4959 } 4960 4961 4962 return; 4963 4964 } /* TransferDateField */ 4965 4966 #endif 4967 4968 /*----------------------------------------------------------------------*/ 4969 4970 static void ValueChangedCB(Widget tw,XmUbTimeBoxWidget tbox,XmAnyCallbackStruct * call_data)4971 ValueChangedCB( Widget tw, 4972 XmUbTimeBoxWidget tbox, 4973 XmAnyCallbackStruct *call_data ) 4974 { 4975 /* Variables. */ 4976 XmUbTimeBoxCallbackStruct cb; 4977 4978 /* Code. */ 4979 4980 if( tbox -> tbox.value_changed_callback == NULL ) 4981 return; 4982 4983 /* Set up callback structure. */ 4984 4985 cb.reason = XmCR_VALUE_CHANGED; 4986 cb.event = call_data -> event; 4987 cb.child_index = ChildIndex( tbox, tw ); 4988 cb.child = tw; 4989 4990 XtCallCallbackList( (Widget) tbox, 4991 tbox -> tbox.value_changed_callback, 4992 (XtPointer) &cb ); 4993 4994 4995 return; 4996 4997 } /* ValueChangedCB */ 4998 4999 5000 /*----------------------------------------------------------------------*/ 5001 5002 static void WarningNoResourceChange(XmUbTimeBoxWidget tbox,String resource)5003 WarningNoResourceChange( XmUbTimeBoxWidget tbox, 5004 String resource ) 5005 { 5006 /* Variables. */ 5007 Cardinal num_params; 5008 String params[ 2 ]; 5009 5010 /* Code. */ 5011 5012 params[ 0 ] = resource; 5013 params[ 1 ] = XtClass( tbox ) -> core_class.class_name; 5014 num_params = 2; 5015 XtAppWarningMsg( XtWidgetToApplicationContext( (Widget) tbox ), 5016 "resourceError", "setValues", "WidgetError", 5017 "Resource %s may not be changed in %s widgets.", 5018 params, &num_params ); 5019 5020 return; 5021 5022 } /* WarningNoResourceChange */ 5023 5024 5025 /*----------------------------------------------------------------------*/ 5026 5027 Widget XmUbCreateTimeBox(Widget parent,String name,ArgList arglist,Cardinal argcount)5028 XmUbCreateTimeBox( Widget parent, 5029 String name, 5030 ArgList arglist, 5031 Cardinal argcount ) 5032 { 5033 5034 /* Code. */ 5035 5036 return XtCreateWidget( name, xmUbTimeBoxWidgetClass, 5037 parent, arglist, argcount ); 5038 5039 } /* XmUbCreateTimeBox */ 5040 5041 5042 /*----------------------------------------------------------------------*/ 5043 5044 Widget XmUbTimeBoxGetChild(Widget widget,int child)5045 XmUbTimeBoxGetChild( Widget widget, 5046 int child ) 5047 { 5048 5049 /* Variables. */ 5050 XmUbTimeBoxWidget tbox; 5051 5052 /* Code. */ 5053 5054 tbox = (XmUbTimeBoxWidget) widget; 5055 5056 5057 return( tbox -> tbox.internal_children[ child ] ); 5058 5059 5060 } /* XmUbTimeBoxGetChild */ 5061 5062 5063 /*----------------------------------------------------------------------*/ 5064 5065 XmUbTimeBoxStatus XmUbTimeBoxGetEndDateString(Widget widget,char ** str)5066 XmUbTimeBoxGetEndDateString( Widget widget, 5067 char **str ) 5068 { 5069 /* Variables. */ 5070 XmUbTimeBoxStatus status; 5071 5072 /* Code. */ 5073 5074 status = GetChildString( (XmUbTimeBoxWidget) widget, 5075 XmUbTB_CHILD_END_DATE, str ); 5076 5077 5078 return( status ); 5079 5080 } /* XmUbTimeBoxGetEndDateString */ 5081 5082 5083 /*----------------------------------------------------------------------*/ 5084 5085 XmUbTimeBoxStatus XmUbTimeBoxGetEndTimeString(Widget widget,char ** str)5086 XmUbTimeBoxGetEndTimeString( Widget widget, 5087 char **str ) 5088 { 5089 /* Variables. */ 5090 XmUbTimeBoxStatus status; 5091 5092 /* Code. */ 5093 5094 status = GetChildString( (XmUbTimeBoxWidget) widget, 5095 XmUbTB_CHILD_END_TIME, str ); 5096 5097 5098 return( status ); 5099 5100 } /* XmUbTimeBoxGetEndTimeString */ 5101 5102 5103 /*----------------------------------------------------------------------*/ 5104 5105 XmUbTimeBoxStatus XmUbTimeBoxGetStartDateString(Widget widget,char ** str)5106 XmUbTimeBoxGetStartDateString( Widget widget, 5107 char **str ) 5108 { 5109 /* Variables. */ 5110 XmUbTimeBoxStatus status; 5111 5112 /* Code. */ 5113 5114 status = GetChildString( (XmUbTimeBoxWidget) widget, 5115 XmUbTB_CHILD_START_DATE, str ); 5116 5117 5118 return( status ); 5119 5120 } /* XmUbTimeBoxGetStartDateString */ 5121 5122 5123 /*----------------------------------------------------------------------*/ 5124 5125 XmUbTimeBoxStatus XmUbTimeBoxGetStartTimeString(Widget widget,char ** str)5126 XmUbTimeBoxGetStartTimeString( Widget widget, 5127 char **str ) 5128 { 5129 /* Variables. */ 5130 XmUbTimeBoxStatus status; 5131 5132 /* Code. */ 5133 5134 status = GetChildString( (XmUbTimeBoxWidget) widget, 5135 XmUbTB_CHILD_START_TIME, str ); 5136 5137 5138 return( status ); 5139 5140 } /* XmUbTimeBoxGetStartTimeString */ 5141 5142 5143 /*----------------------------------------------------------------------*/ 5144 5145 XmUbTimeBoxStatus XmUbTimeBoxGetEndDate(Widget widget,time_t * date)5146 XmUbTimeBoxGetEndDate( Widget widget, 5147 time_t *date ) 5148 { 5149 /* Variables. */ 5150 char *datestr; 5151 XmUbTimeBoxStatus status; 5152 TIM_STATUS_TYPE tim_status; 5153 TIM_TIME_REF tmp_date; 5154 5155 /* Code. */ 5156 5157 status = XmUbTimeBoxGetEndDateString( widget, &datestr ); 5158 5159 if( status != TBOX_OK ) 5160 return( status ); 5161 5162 /* Try to convert to date. */ 5163 tim_status = TimMakeDateFromString( &tmp_date, datestr ); 5164 5165 if( tim_status == TIM_OK ) 5166 *date = tmp_date; 5167 else 5168 status = TBOX_CONV_ERROR; 5169 5170 /* Cleanup. */ 5171 XtFree( datestr ); 5172 5173 5174 return( status ); 5175 5176 } /* XmUbTimeBoxGetEndDate */ 5177 5178 5179 /*----------------------------------------------------------------------*/ 5180 5181 XmUbTimeBoxStatus XmUbTimeBoxGetStartDate(Widget widget,time_t * date)5182 XmUbTimeBoxGetStartDate( Widget widget, 5183 time_t *date ) 5184 { 5185 /* Variables. */ 5186 char *datestr; 5187 XmUbTimeBoxStatus status; 5188 TIM_STATUS_TYPE tim_status; 5189 TIM_TIME_REF tmp_date; 5190 5191 /* Code. */ 5192 5193 status = XmUbTimeBoxGetStartDateString( widget, &datestr ); 5194 5195 if( status != TBOX_OK ) 5196 return( status ); 5197 5198 /* Try to convert to date. */ 5199 tim_status = TimMakeDateFromString( &tmp_date, datestr ); 5200 5201 if( tim_status == TIM_OK ) 5202 *date = tmp_date; 5203 else 5204 status = TBOX_CONV_ERROR; 5205 5206 /* Cleanup. */ 5207 XtFree( datestr ); 5208 5209 5210 return( status ); 5211 5212 } /* XmUbTimeBoxGetStartDate */ 5213 5214 5215 /*----------------------------------------------------------------------*/ 5216 5217 XmUbTimeBoxStatus XmUbTimeBoxGetEndTime(Widget widget,time_t * time)5218 XmUbTimeBoxGetEndTime( Widget widget, 5219 time_t *time ) 5220 { 5221 /* Variables. */ 5222 char *timestr; 5223 XmUbTimeBoxStatus status; 5224 TIM_STATUS_TYPE tim_status; 5225 TIM_TIME_REF tmp_time; 5226 5227 /* Code. */ 5228 5229 status = XmUbTimeBoxGetEndTimeString( widget, ×tr ); 5230 5231 if( status != TBOX_OK ) 5232 return( status ); 5233 5234 /* Try to convert to date. */ 5235 tim_status = TimMakeTimeFromString( &tmp_time, timestr ); 5236 5237 if( tim_status == TIM_OK ) 5238 *time = tmp_time; 5239 else 5240 status = TBOX_CONV_ERROR; 5241 5242 /* Cleanup. */ 5243 XtFree( timestr ); 5244 5245 5246 return( status ); 5247 5248 } /* XmUbTimeBoxGetEndTime */ 5249 5250 5251 /*----------------------------------------------------------------------*/ 5252 5253 XmUbTimeBoxStatus XmUbTimeBoxGetStartTime(Widget widget,time_t * time)5254 XmUbTimeBoxGetStartTime( Widget widget, 5255 time_t *time ) 5256 { 5257 /* Variables. */ 5258 char *timestr; 5259 XmUbTimeBoxStatus status; 5260 TIM_STATUS_TYPE tim_status; 5261 TIM_TIME_REF tmp_time; 5262 5263 /* Code. */ 5264 5265 status = XmUbTimeBoxGetStartTimeString( widget, ×tr ); 5266 5267 if( status != TBOX_OK ) 5268 return( status ); 5269 5270 /* Try to convert to date. */ 5271 tim_status = TimMakeTimeFromString( &tmp_time, timestr ); 5272 5273 if( tim_status == TIM_OK ) 5274 *time = tmp_time; 5275 else 5276 status = TBOX_CONV_ERROR; 5277 5278 /* Cleanup. */ 5279 XtFree( timestr ); 5280 5281 5282 return( status ); 5283 5284 } /* XmUbTimeBoxGetStartTime */ 5285 5286 5287 /*----------------------------------------------------------------------*/ 5288 5289 XmUbTimeBoxStatus XmUbTimeBoxSetEndDate(Widget widget,time_t date)5290 XmUbTimeBoxSetEndDate( Widget widget, 5291 time_t date ) 5292 { 5293 /* Variables. */ 5294 char buffer[ TIME_STRING_BUFFER_LEN ]; 5295 XmUbTimeBoxWidget tbox; 5296 5297 /* Code. */ 5298 5299 tbox = (XmUbTimeBoxWidget) widget; 5300 5301 /* Convert the date to a string. */ 5302 ConvertToDateString( tbox, date, buffer, TIME_STRING_BUFFER_LEN - 1 ); 5303 5304 /* Set the string. */ 5305 return( SetChildString( tbox, XmUbTB_CHILD_END_DATE, buffer ) ); 5306 5307 } /* XmUbTimeBoxSetEndDate */ 5308 5309 5310 /*----------------------------------------------------------------------*/ 5311 5312 XmUbTimeBoxStatus XmUbTimeBoxSetEndTime(Widget widget,time_t time)5313 XmUbTimeBoxSetEndTime( Widget widget, 5314 time_t time ) 5315 { 5316 /* Variables. */ 5317 char buffer[ TIME_STRING_BUFFER_LEN ]; 5318 XmUbTimeBoxWidget tbox; 5319 5320 /* Code. */ 5321 5322 tbox = (XmUbTimeBoxWidget) widget; 5323 5324 /* Convert the date to a string. */ 5325 ConvertToTimeString( tbox, time, buffer, TIME_STRING_BUFFER_LEN - 1 ); 5326 5327 /* Set the string. */ 5328 return( SetChildString( tbox, XmUbTB_CHILD_END_TIME, buffer ) ); 5329 5330 } /* XmUbTimeBoxSetEndTime */ 5331 5332 5333 /*----------------------------------------------------------------------*/ 5334 5335 XmUbTimeBoxStatus XmUbTimeBoxSetStartDate(Widget widget,time_t date)5336 XmUbTimeBoxSetStartDate( Widget widget, 5337 time_t date ) 5338 { 5339 /* Variables. */ 5340 char buffer[ TIME_STRING_BUFFER_LEN ]; 5341 XmUbTimeBoxWidget tbox; 5342 5343 /* Code. */ 5344 5345 tbox = (XmUbTimeBoxWidget) widget; 5346 5347 /* Convert the date to a string. */ 5348 ConvertToDateString( tbox, date, buffer, TIME_STRING_BUFFER_LEN - 1 ); 5349 5350 /* Set the string. */ 5351 return( SetChildString( tbox, XmUbTB_CHILD_START_DATE, buffer ) ); 5352 5353 } /* XmUbTimeBoxSetStartDate */ 5354 5355 5356 /*----------------------------------------------------------------------*/ 5357 5358 XmUbTimeBoxStatus XmUbTimeBoxSetStartTime(Widget widget,time_t time)5359 XmUbTimeBoxSetStartTime( Widget widget, 5360 time_t time ) 5361 { 5362 /* Variables. */ 5363 char buffer[ TIME_STRING_BUFFER_LEN ]; 5364 XmUbTimeBoxWidget tbox; 5365 5366 /* Code. */ 5367 5368 tbox = (XmUbTimeBoxWidget) widget; 5369 5370 /* Convert the date to a string. */ 5371 ConvertToTimeString( tbox, time, buffer, TIME_STRING_BUFFER_LEN - 1 ); 5372 5373 /* Set the string. */ 5374 return( SetChildString( tbox, XmUbTB_CHILD_START_TIME, buffer ) ); 5375 5376 } /* XmUbTimeBoxSetStartTime */ 5377 5378 5379 /*----------------------------------------------------------------------*/ 5380 5381 XmUbTimeBoxStatus XmUbTimeBoxSetEndDateString(Widget widget,char * str)5382 XmUbTimeBoxSetEndDateString( Widget widget, 5383 char *str ) 5384 { 5385 /* Code. */ 5386 5387 return( SetChildString( (XmUbTimeBoxWidget) widget, 5388 XmUbTB_CHILD_END_DATE, str ) ); 5389 5390 } /* XmUbTimeBoxSetEndDateString */ 5391 5392 5393 /*----------------------------------------------------------------------*/ 5394 5395 XmUbTimeBoxStatus XmUbTimeBoxSetEndTimeString(Widget widget,char * str)5396 XmUbTimeBoxSetEndTimeString( Widget widget, 5397 char *str ) 5398 { 5399 /* Code. */ 5400 5401 return( SetChildString( (XmUbTimeBoxWidget) widget, 5402 XmUbTB_CHILD_END_TIME, str ) ); 5403 5404 } /* XmUbTimeBoxSetEndTimeString */ 5405 5406 5407 /*----------------------------------------------------------------------*/ 5408 5409 XmUbTimeBoxStatus XmUbTimeBoxSetStartDateString(Widget widget,char * str)5410 XmUbTimeBoxSetStartDateString( Widget widget, 5411 char *str ) 5412 { 5413 /* Code. */ 5414 5415 return( SetChildString( (XmUbTimeBoxWidget) widget, 5416 XmUbTB_CHILD_START_DATE, str ) ); 5417 5418 } /* XmUbTimeBoxSetStartDateString */ 5419 5420 5421 /*----------------------------------------------------------------------*/ 5422 5423 XmUbTimeBoxStatus XmUbTimeBoxSetStartTimeString(Widget widget,char * str)5424 XmUbTimeBoxSetStartTimeString( Widget widget, 5425 char *str ) 5426 { 5427 /* Code. */ 5428 5429 return( SetChildString( (XmUbTimeBoxWidget) widget, 5430 XmUbTB_CHILD_START_TIME, str ) ); 5431 5432 } /* XmUbTimeBoxSetStartTimeString */ 5433 5434 5435 /*----------------------------------------------------------------------*/ 5436 5437 void XmUbTimeBoxPopupDateDialog(Widget widget,int child_index)5438 XmUbTimeBoxPopupDateDialog( Widget widget, 5439 int child_index ) 5440 { 5441 /* Variables. */ 5442 Widget child; 5443 5444 /* Code. */ 5445 5446 child = XmUbTimeBoxGetChild( widget, child_index ); 5447 5448 if( child != NULL ) 5449 PopupDateSelection( child ); 5450 5451 5452 return; 5453 5454 } /* XmUbTimeBoxPopupDateDialog */ 5455 5456 5457 /*----------------------------------------------------------------------*/ 5458 5459 void XmUbTimeBoxPopupTimeDialog(Widget widget,int child_index)5460 XmUbTimeBoxPopupTimeDialog( Widget widget, 5461 int child_index ) 5462 { 5463 /* Variables. */ 5464 Widget child; 5465 5466 /* Code. */ 5467 5468 child = XmUbTimeBoxGetChild( widget, child_index ); 5469 5470 if( child != NULL ) 5471 PopupTimeSelection( child ); 5472 5473 5474 return; 5475 5476 } /* XmUbTimeBoxPopupTimeDialog */ 5477