1 /*---------------------------------------------------------------------------- 2 -- 3 -- Module: xtmDbMisc 4 -- 5 -- Project: Xdiary 6 -- System: xtm - X Desktop Calendar 7 -- Subsystem: <> 8 -- Function block: <> 9 -- 10 -- Description: 11 -- High-level interface to the diary database. Provides functions that 12 -- work on databses with include lists. 13 -- 14 -- Filename: xtmDbMisc.c 15 -- 16 -- Authors: Roger Larsson, Ulrika Bornetun 17 -- Creation date: 1992-01-09 18 -- 19 -- 20 -- (C) Copyright Ulrika Bornetun, Roger Larsson (1995) 21 -- All rights reserved 22 -- 23 -- Permission to use, copy, modify, and distribute this software and its 24 -- documentation for any purpose and without fee is hereby granted, 25 -- provided that the above copyright notice appear in all copies. Ulrika 26 -- Bornetun and Roger Larsson make no representations about the usability 27 -- of this software for any purpose. It is provided "as is" without express 28 -- or implied warranty. 29 ----------------------------------------------------------------------------*/ 30 31 /* SCCS module identifier. */ 32 static char SCCSID[] = "@(#) Module: xtmDbMisc.c, Version: 1.1, Date: 95/02/18 15:52:09"; 33 34 35 /*---------------------------------------------------------------------------- 36 -- Include files 37 ----------------------------------------------------------------------------*/ 38 39 #include <stdio.h> 40 #include <ctype.h> 41 #include <sys/types.h> 42 #include <unistd.h> 43 44 #include <X11/Intrinsic.h> 45 #include <X11/cursorfont.h> 46 47 #include <Xm/Xm.h> 48 49 #include "System.h" 50 #include "LstLinked.h" 51 #include "Message.h" 52 #include "TimDate.h" 53 54 #include "msgXdiary.h" 55 #include "xtmGlobal.h" 56 #include "xtmAccBase.h" 57 #include "xtmCalDb.h" 58 #include "xtmCustBase.h" 59 #include "xtmDbTools.h" 60 #include "xitError.h" 61 #include "xitTools.h" 62 #include "xtmDbMisc.h" 63 64 65 /*---------------------------------------------------------------------------- 66 -- Macro definitions 67 ----------------------------------------------------------------------------*/ 68 69 /* Priorities. */ 70 #define PRIO_TAG (1<<0) 71 #define PRIO_NOTE_NOT_DONE (1<<1) 72 #define PRIO_IMPORTANT (1<<2) 73 74 75 /*---------------------------------------------------------------------------- 76 -- Type declarations 77 ----------------------------------------------------------------------------*/ 78 79 80 /*---------------------------------------------------------------------------- 81 -- Global definitions 82 ----------------------------------------------------------------------------*/ 83 84 /* Name of module. */ 85 static char *module_name = "xtmDbMisc"; 86 87 88 /*---------------------------------------------------------------------------- 89 -- Function prototypes 90 ----------------------------------------------------------------------------*/ 91 92 static void 93 checkEntries( XTM_GL_BASE_DATA_REF appl_data_ref, 94 char *db_name, 95 TIM_TIME_REF date, 96 int days, 97 Boolean show_standing, 98 Boolean entry_defined[] ); 99 100 static void 101 deleteEntryCB( void *element ); 102 103 static LST_COMPARE 104 entrySortFunc( XTM_DB_ALL_ENTRY_REF list_entry_ref, 105 XTM_DB_ALL_ENTRY_REF search_entry_ref ); 106 107 static XTM_DB_STATUS 108 fetchFilteredEntriesDay( XTM_GL_BASE_DATA_REF appl_data_ref, 109 char *db_name, 110 UINT32 flags, 111 XtAppContext context, 112 Widget workW, 113 TIM_TIME_REF starts, 114 TIM_TIME_REF ends, 115 XTM_DM_FILTER_REC *filter_ref, 116 LST_DESC_TYPE entries ); 117 118 static Boolean 119 searchString( char *search_string, 120 Boolean case_sens1, 121 char *in_string, 122 Boolean case_sens2 ); 123 124 125 126 /*---------------------------------------------------------------------------- 127 -- Functions 128 ----------------------------------------------------------------------------*/ 129 130 void xtmDmDeleteEntriesList(LST_DESC_TYPE entries)131 xtmDmDeleteEntriesList( LST_DESC_TYPE entries ) 132 { 133 134 /* Code. */ 135 136 LstLinkClearDataAndList( entries, deleteEntryCB ); 137 138 139 return; 140 141 } /* xtmDmDeleteEntriesList */ 142 143 144 /*----------------------------------------------------------------------*/ 145 146 Boolean xtmDmDeleteEntry(Widget parentW,XTM_DB_ENTRY_DATABASES * database,UINT32 entry_id)147 xtmDmDeleteEntry( Widget parentW, 148 XTM_DB_ENTRY_DATABASES *database, 149 UINT32 entry_id ) 150 { 151 152 /* Variables. */ 153 XTM_DB_STATUS db_status; 154 155 156 /* Code. */ 157 158 /* Delete the entry. */ 159 db_status = xtmDbDeleteEntry( database, entry_id ); 160 161 if( db_status != XTM_DB_OK ) { 162 xitErMessage( parentW, XIT_ER_ERROR, 163 module_name, "xtmDmDeleteEntry", 164 msgGetText( MXDI_ERRMSG_DELETE_ENTRY ) ); 165 166 return( False ); 167 } 168 169 170 return( True ); 171 172 } /* xtmDmDeleteEntry */ 173 174 175 /*----------------------------------------------------------------------*/ 176 177 Boolean xtmDmFetchEntry(Widget parentW,XTM_DB_ENTRY_DATABASES * database,UINT32 entry_id,XTM_DB_ALL_ENTRY_REF entry_ref,char ** entry_text)178 xtmDmFetchEntry( Widget parentW, 179 XTM_DB_ENTRY_DATABASES *database, 180 UINT32 entry_id, 181 XTM_DB_ALL_ENTRY_REF entry_ref, 182 char **entry_text ) 183 { 184 185 /* Variables. */ 186 XTM_DB_STATUS db_status; 187 188 189 /* Code. */ 190 191 /* Fetch the entry. */ 192 db_status = xtmDbFetchEntry( database, entry_id, 193 entry_ref, entry_text ); 194 195 if( db_status != XTM_DB_OK ) { 196 xitErMessage( parentW, XIT_ER_ERROR, 197 module_name, "xtmDmFetchEntry", 198 msgGetText( MXDI_NO_ENTRY ) ); 199 200 return( False ); 201 } 202 203 204 return( True ); 205 206 } /* xtmDmFetchEntry */ 207 208 209 /*----------------------------------------------------------------------*/ 210 211 XTM_DB_STATUS xtmDmFetchFilteredEntriesRange(XTM_GL_BASE_DATA_REF appl_data_ref,char * db_name,XtAppContext context,Widget parent,TIM_TIME_REF starts,TIM_TIME_REF ends,UINT32 flags,XTM_DM_FILTER_REC * filter_ref,LST_DESC_TYPE * entries)212 xtmDmFetchFilteredEntriesRange( XTM_GL_BASE_DATA_REF appl_data_ref, 213 char *db_name, 214 XtAppContext context, 215 Widget parent, 216 TIM_TIME_REF starts, 217 TIM_TIME_REF ends, 218 UINT32 flags, 219 XTM_DM_FILTER_REC *filter_ref, 220 LST_DESC_TYPE *entries ) 221 { 222 223 /* Variables. */ 224 Boolean ok; 225 int index; 226 char buffer[ 100 ]; 227 char *char_ref; 228 Cursor wait_cursor; 229 Widget workW = NULL; 230 TIM_DELTA_TYPE delta; 231 XTM_DB_STATUS db_status; 232 XTM_GL_CUSTOM_DATA_REF custom_data; 233 XTM_CD_CAL_INFO db_incl_info; 234 XTM_CD_CAL_INFO db_info; 235 XTM_CD_INCL_CALS db_incl; 236 237 238 /* Code. */ 239 240 custom_data = appl_data_ref -> custom_data; 241 *entries = NULL; 242 243 ok = xtmCdFetchNamedDb( custom_data -> cal_db_handle, db_name, 244 &db_info, &db_incl ); 245 if( ! ok ) 246 return( XTM_DB_ERROR ); 247 248 249 *entries = LstLinkNew( sizeof( XTM_DB_ALL_ENTRY_DEF ), NULL ); 250 251 /* Initialize search strings. */ 252 if( flagIsClear( filter_ref -> flags, XTM_DM_FLAG_TEXT_CASE_SENS ) ) { 253 char_ref = filter_ref -> text_string; 254 255 while( *char_ref != '\0' ) { 256 *char_ref = toupper( *char_ref ); 257 char_ref++; 258 } 259 } 260 261 if( flagIsClear( filter_ref -> flags, XTM_DM_FLAG_TAG_CASE_SENS ) ) { 262 char_ref = filter_ref -> tag_string; 263 264 while( *char_ref != '\0' ) { 265 *char_ref = toupper( *char_ref ); 266 char_ref++; 267 } 268 } 269 270 271 /* Display a working form? */ 272 TimDelta( starts, ends, &delta ); 273 274 if( parent != NULL ) { 275 if( delta.days > 31 ) { 276 workW = xitCreateBusyDialog( 277 parent, "WorkingDialog", 278 msgGetText( MXDI_WORKING_TITLE ), 279 msgGetText( MXDI_WORKING_MESSAGE ) ); 280 } else { 281 wait_cursor = XCreateFontCursor( XtDisplay( parent ), XC_watch ); 282 XDefineCursor( XtDisplay( parent ), XtWindow( parent ), wait_cursor ); 283 284 XFlush( XtDisplay( parent ) ); 285 } 286 } 287 288 /* Process the main database. */ 289 db_status = fetchFilteredEntriesDay( appl_data_ref, 290 db_name, flags, 291 context, workW, 292 starts, ends, 293 filter_ref, *entries ); 294 if( db_status != XTM_DB_OK ) 295 raise exception; 296 297 /* Process the included databases. */ 298 if( db_status == XTM_DB_OK && 299 db_incl.no > 0 && 300 flagIsClear( flags, XTM_DB_FETCH_SKIP_INCLUDE ) ) { 301 302 flagSet( flags, XTM_DB_FETCH_INCLUDE ); 303 304 for( index = 0; index < db_incl.no; index++ ) { 305 306 /* Search the database info. */ 307 ok = xtmCdFetchNamedDb( custom_data -> cal_db_handle, 308 db_incl.db[ index ].name, 309 &db_incl_info, NULL ); 310 if( ! ok ) { 311 sprintf( buffer, 312 msgGetText( MXDI_ERRMSG_FETCH_NAMED_DB ), 313 db_incl_info.directory ); 314 315 xitErMessage( parent, XIT_ER_ERROR, 316 module_name, "xtmDmFetchCompleteDay", 317 buffer ); 318 continue; 319 } 320 321 /* We must have at least read access. */ 322 if( ! flagIsSet( db_incl_info.operations, XTM_DB_FLAG_MODE_READ ) ) { 323 sprintf( buffer, 324 msgGetText( MXDI_ERRMSG_NO_ACCESS_NAMED_DB ), 325 db_incl_info.directory ); 326 327 xitErMessage( NULL, XIT_ER_ERROR, 328 module_name, "xtmDmFetchCompleteDay", 329 buffer ); 330 continue; 331 } 332 333 /* Fetch entries in the include database. */ 334 db_status = fetchFilteredEntriesDay( appl_data_ref, 335 db_incl.db[ index ].name, 336 flags, 337 context, workW, 338 starts, ends, 339 filter_ref, *entries ); 340 if( db_status != XTM_DB_OK ) 341 raise exception; 342 343 } /* loop */ 344 345 } /* if */ 346 347 348 if( parent != NULL ) { 349 if( workW != NULL ) 350 xitBusyDialogRemove( workW ); 351 else 352 XUndefineCursor( XtDisplay( parent ), XtWindow( parent ) ); 353 } 354 355 356 return( XTM_DB_OK ); 357 358 359 /* Exception handler. */ 360 exception: 361 if( workW != NULL ) 362 xitBusyDialogRemove( workW ); 363 364 return( db_status ); 365 366 } /* xtmDmFetchFilteredEntriesRange */ 367 368 369 /*----------------------------------------------------------------------*/ 370 371 Boolean xtmDmInsertEntry(Widget parentW,XTM_DB_ENTRY_DATABASES * database,UINT32 entry_id,XTM_DB_ALL_ENTRY_REF entry_ref,char * entry_text)372 xtmDmInsertEntry( Widget parentW, 373 XTM_DB_ENTRY_DATABASES *database, 374 UINT32 entry_id, 375 XTM_DB_ALL_ENTRY_REF entry_ref, 376 char *entry_text ) 377 { 378 379 /* Variables. */ 380 UINT32 id; 381 XTM_DB_ID_REQUEST id_request; 382 XTM_DB_STATUS db_status; 383 384 385 /* Code. */ 386 387 /* Generate a new id for the entry. */ 388 id_request.directory = database -> database_dir; 389 id_request.operations = 0; 390 id_request.lock_file = False; 391 392 db_status = xtmDbGenerateId( &id_request, &id ); 393 if( db_status != XTM_DB_OK ) 394 xitErMessage( NULL, XIT_ER_FATAL, 395 module_name, "xtmDmInsertEntry", 396 msgGetText( MXDI_ERRMSG_GENERATE_ID ) ); 397 398 /* New data for entry to save. */ 399 entry_ref -> entry.id = id; 400 entry_ref -> stand_entry.id = id; 401 402 /* Save the new entry. */ 403 db_status = xtmDbInsertEntry( database, 404 entry_ref, entry_text ); 405 406 if( db_status != XTM_DB_OK ) 407 xitErMessage( NULL, XIT_ER_FATAL, 408 module_name, "xtmDmInsertEntry", 409 msgGetText( MXDI_ERRMSG_INSERT_ENTRY ) ); 410 411 412 return( True ); 413 414 } /* xtmDmInsertEntry */ 415 416 417 /*----------------------------------------------------------------------*/ 418 419 void xtmDmEntriesDefined(XTM_GL_BASE_DATA_REF appl_data_ref,char * db_name,TIM_TIME_REF date,int days,Boolean include_db,Boolean show_standing,Boolean entry_defined[])420 xtmDmEntriesDefined( XTM_GL_BASE_DATA_REF appl_data_ref, 421 char *db_name, 422 TIM_TIME_REF date, 423 int days, 424 Boolean include_db, 425 Boolean show_standing, 426 Boolean entry_defined[] ) 427 { 428 429 /* Variables. */ 430 Boolean ok; 431 int index; 432 XTM_GL_CUSTOM_DATA_REF custom_data; 433 XTM_CD_CAL_INFO db_incl_info; 434 XTM_CD_CAL_INFO db_info; 435 XTM_CD_INCL_CALS db_incl; 436 437 438 /* Code. */ 439 440 custom_data = appl_data_ref -> custom_data; 441 442 for( index = 0; index < days; index++ ) 443 entry_defined[ index ] = False; 444 445 446 /* Check the main database. */ 447 checkEntries( appl_data_ref, db_name, 448 date, days, show_standing, entry_defined ); 449 450 451 /* Fetch the calendar information. */ 452 (void) xtmCdFetchNamedDb( appl_data_ref -> custom_data -> cal_db_handle, 453 db_name, 454 &db_info, &db_incl ); 455 456 457 /* Check the included databases? */ 458 if( db_incl.no == 0 || ! include_db ) 459 return; 460 461 for( index = 0; index < db_incl.no; index++ ) { 462 ok = xtmCdFetchNamedDb( custom_data -> cal_db_handle, 463 db_incl.db[ index ].name, 464 &db_incl_info, NULL ); 465 466 if( ! ok || flagIsSet( db_incl_info.flags, XTM_CD_FLAG_HIDE_IN_CAL ) ) 467 continue; 468 469 checkEntries( appl_data_ref, 470 db_incl.db[ index ].name, 471 date, days, show_standing, entry_defined ); 472 } /* loop */ 473 474 475 return; 476 477 } /* xtmDmEntriesDefined */ 478 479 480 /*----------------------------------------------------------------------*/ 481 482 Boolean xtmDmOpenDatabase(XTM_GL_BASE_DATA_REF appl_data_ref,char * db_name,UINT32 access_mode,XTM_DB_ENTRY_DATABASES * database_ref)483 xtmDmOpenDatabase( XTM_GL_BASE_DATA_REF appl_data_ref, 484 char *db_name, 485 UINT32 access_mode, 486 XTM_DB_ENTRY_DATABASES *database_ref ) 487 { 488 489 /* Variables. */ 490 Boolean ok; 491 char buffer[ 200 ]; 492 XTM_DB_OPEN_REQUEST open_request; 493 XTM_DB_STATUS db_status; 494 XTM_CD_CAL_INFO db_info; 495 496 497 /* Code. */ 498 499 /* Fetch database information. */ 500 ok = xtmCdFetchNamedDb( appl_data_ref -> custom_data -> cal_db_handle, 501 db_name, 502 &db_info, NULL ); 503 if( ! ok ) 504 return( False ); 505 506 507 /* Do we have the necessary access? */ 508 if( ! flagIsSet( db_info.operations, access_mode ) ) { 509 sprintf( buffer, 510 msgGetText( MXDI_ERRMSG_NO_ACCESS_NAMED_DB ), 511 db_info.short_name ); 512 513 xitMsgWinDisplayMessage( appl_data_ref -> msg_win_ref, buffer, 0 ); 514 return( False ); 515 } 516 517 518 /* Open the database to write the new entry. */ 519 open_request.name = db_info.short_name; 520 open_request.directory = db_info.directory; 521 open_request.operations = access_mode; 522 open_request.database = XTM_DB_ALL_ENTRY_DB; 523 524 db_status = xtmDbOpenEntryDb( &open_request, database_ref ); 525 526 if( db_status != XTM_DB_OK ) { 527 528 if( db_status == XTM_DB_LOCKED ) { 529 sprintf( buffer, "%s: %s", 530 db_info.short_name, msgGetText( MXDI_ERRMSG_DB_LOCKED ) ); 531 532 xitMsgWinDisplayMessage( appl_data_ref -> msg_win_ref, buffer, 0 ); 533 } else { 534 sprintf( buffer, "%s: %s", 535 db_info.short_name, msgGetText( MXDI_ERRMSG_CANNOT_OPEN_DB ) ); 536 537 xitMsgWinDisplayMessage( appl_data_ref -> msg_win_ref, buffer, 0 ); 538 } 539 540 return( False ); 541 } 542 543 544 return( True ); 545 546 } /* xtmDmOpenDatabase */ 547 548 549 /*----------------------------------------------------------------------*/ 550 551 static void checkEntries(XTM_GL_BASE_DATA_REF appl_data_ref,char * db_name,TIM_TIME_REF date,int days,Boolean show_standing,Boolean entry_defined[])552 checkEntries( XTM_GL_BASE_DATA_REF appl_data_ref, 553 char *db_name, 554 TIM_TIME_REF date, 555 int days, 556 Boolean show_standing, 557 Boolean entry_defined[] ) 558 { 559 560 /* Variables. */ 561 Boolean ok; 562 int index; 563 LST_DESC_TYPE stand_entries[ 2 ]; 564 TIM_TIME_REF curr_date; 565 XTM_DB_ENTRY_DATABASES database; 566 567 568 /* Code. */ 569 570 /* Open the database for this calendar. */ 571 ok = xtmDmOpenDatabase( appl_data_ref, 572 db_name, XTM_DB_FLAG_MODE_READ, 573 &database ); 574 if( ! ok ) 575 return; 576 577 /* Fetch all standing entries? */ 578 stand_entries[ 0 ] = NULL; 579 stand_entries[ 1 ] = NULL; 580 581 if( show_standing ) 582 (void) xtmDbFetchStandEntries( &database, 583 &stand_entries[ 0 ], 584 &stand_entries[ 1 ] ); 585 586 /* Start the 1st of the month. */ 587 curr_date = date; 588 589 /* Check all days. */ 590 for( index = 0; index < days; index++ ) { 591 592 if( ! entry_defined[ index ] ) 593 entry_defined[ index ] = xtmDbIsEntryDefined( &database, 594 stand_entries, curr_date ); 595 TimAddDays( &curr_date, 1 ); 596 597 } /* loop */ 598 599 600 /* Free the standing entries. */ 601 LstLinkClear( stand_entries[ 0 ] ); 602 LstLinkClear( stand_entries[ 1 ] ); 603 604 /* Close the database again. */ 605 xtmDbCloseEntryDb( &database ); 606 607 608 return; 609 610 } /* checkEntries */ 611 612 613 /*----------------------------------------------------------------------*/ 614 615 static void deleteEntryCB(void * element)616 deleteEntryCB( void *element ) 617 { 618 619 /* Variables. */ 620 XTM_DB_ALL_ENTRY_DEF *entry_ref; 621 622 623 /* Code. */ 624 625 entry_ref = (XTM_DB_ALL_ENTRY_DEF *) element; 626 627 if( entry_ref -> all_text != NULL ) 628 SysFree( entry_ref -> all_text ); 629 630 631 return; 632 633 } /* deleteEntryCB */ 634 635 636 /*----------------------------------------------------------------------*/ 637 638 static LST_COMPARE entrySortFunc(XTM_DB_ALL_ENTRY_REF list_entry_ref,XTM_DB_ALL_ENTRY_REF search_entry_ref)639 entrySortFunc( XTM_DB_ALL_ENTRY_REF list_entry_ref, 640 XTM_DB_ALL_ENTRY_REF search_entry_ref ) 641 { 642 643 /* Variables. */ 644 UINT32 list_entry_prio = 0; 645 UINT32 search_entry_prio = 0; 646 char *list_tag; 647 char *search_tag; 648 649 650 /* Code. */ 651 652 /* Correct day? */ 653 if( search_entry_ref -> entry.date_stamp > 654 list_entry_ref -> entry.date_stamp ) 655 return( LST_NOT_EQUAL ); 656 657 if( search_entry_ref -> entry.date_stamp < 658 list_entry_ref -> entry.date_stamp ) 659 return( LST_EQUAL ); 660 661 662 663 /* Sort notes? */ 664 if( search_entry_ref -> entry.entry_type == XTM_DB_DAY_NOTE ) { 665 666 if( list_entry_ref -> entry.entry_type != XTM_DB_DAY_NOTE ) 667 return( LST_EQUAL ); 668 669 /* Ranking for entry to insert. */ 670 if( flagIsSet( search_entry_ref -> entry.flags, XTM_DB_FLAG_IMPORTANT ) ) 671 flagSet( search_entry_prio, PRIO_IMPORTANT ); 672 673 if( flagIsClear( search_entry_ref -> entry.flags, XTM_DB_FLAG_NOTE_DONE ) ) 674 flagSet( search_entry_prio, PRIO_NOTE_NOT_DONE ); 675 676 /* Ranking for entry in list. */ 677 if( flagIsSet( list_entry_ref -> entry.flags, XTM_DB_FLAG_IMPORTANT ) ) 678 flagSet( list_entry_prio, PRIO_IMPORTANT ); 679 680 if( flagIsClear( list_entry_ref -> entry.flags, XTM_DB_FLAG_NOTE_DONE ) ) 681 flagSet( list_entry_prio, PRIO_NOTE_NOT_DONE ); 682 683 /* Tag priority. */ 684 if( search_entry_ref -> entry.tag[ 0 ] == '\0' ) 685 search_tag = "xxxx"; 686 else 687 search_tag = search_entry_ref -> entry.tag; 688 689 if( list_entry_ref -> entry.tag[ 0 ] == '\0' ) 690 list_tag = "xxxx"; 691 else 692 list_tag = list_entry_ref -> entry.tag; 693 694 if( strcmp( search_tag, list_tag ) < 0 ) 695 flagSet( search_entry_prio, PRIO_TAG ); 696 else 697 flagSet( list_entry_prio, PRIO_TAG ); 698 699 700 /* Insert the entry here? */ 701 if( search_entry_prio > list_entry_prio ) 702 return( LST_EQUAL ); 703 704 705 /* Sort appointments? */ 706 } else if( search_entry_ref -> entry.entry_type == XTM_DB_DAY_ENTRY ) { 707 708 if( search_entry_ref -> entry.time_stamp < 709 list_entry_ref -> entry.time_stamp ) 710 return( LST_EQUAL ); 711 712 } /* if */ 713 714 715 return( LST_NOT_EQUAL ); 716 717 } /* entrySortFunc */ 718 719 720 /*----------------------------------------------------------------------*/ 721 722 static XTM_DB_STATUS fetchFilteredEntriesDay(XTM_GL_BASE_DATA_REF appl_data_ref,char * db_name,UINT32 flags,XtAppContext context,Widget workW,TIM_TIME_REF starts,TIM_TIME_REF ends,XTM_DM_FILTER_REC * filter_ref,LST_DESC_TYPE entries)723 fetchFilteredEntriesDay( XTM_GL_BASE_DATA_REF appl_data_ref, 724 char *db_name, 725 UINT32 flags, 726 XtAppContext context, 727 Widget workW, 728 TIM_TIME_REF starts, 729 TIM_TIME_REF ends, 730 XTM_DM_FILTER_REC *filter_ref, 731 LST_DESC_TYPE entries ) 732 { 733 734 /* Variables. */ 735 Boolean case_sens; 736 Boolean match; 737 Boolean ok; 738 int index; 739 UINT32 filter; 740 char *char_ref; 741 TIM_TIME_REF current_date; 742 XTM_DB_ALL_ENTRY_DEF entry_record; 743 XTM_DB_ENTRY_DATABASES database; 744 XTM_DB_STATUS db_status; 745 LST_DESC_TYPE list_ref[ 2 ]; 746 LST_STATUS lst_status; 747 748 749 /* Code. */ 750 751 /* Open the database for this calendar. */ 752 ok = xtmDmOpenDatabase( appl_data_ref, 753 db_name, XTM_DB_FLAG_MODE_READ, 754 &database ); 755 if( ! ok ) 756 return( XTM_DB_ERROR ); 757 758 759 filter = filter_ref -> flags; 760 current_date = starts; 761 762 /* Process all days. */ 763 while( current_date <= ends ) { 764 765 /* Fetch entries this day. */ 766 flagSet( flags, (XTM_DB_FETCH_STANDING | 767 XTM_DB_FETCH_STICKY | 768 XTM_DB_FETCH_ALL_TEXT ) ); 769 770 db_status = xtmDbFetchEntriesInDay( &database, current_date, flags, 771 &list_ref[ 1 ], &list_ref[ 0 ] ); 772 773 if( db_status != XTM_DB_OK ) { 774 xtmDbCloseEntryDb( &database ); 775 776 return( XTM_DB_ERROR ); 777 } 778 779 /* Process the notes and entries. */ 780 for( index = 0; index < 2; index++ ) { 781 782 /* Any elements in the list? */ 783 if( LstLinkElements( list_ref[ index ] ) > 0 ) { 784 785 /* Process all the elements. */ 786 lst_status = LstLinkCurrentFirst( list_ref[ index ] ); 787 while( lst_status == LST_OK ) { 788 789 XTM_DB_ENTRY_REF entry_ref; 790 XTM_DB_STAND_ENTRY_REF stand_entry_ref; 791 792 lst_status = LstLinkGetCurrent( list_ref[ index ], &entry_record ); 793 794 entry_ref = &entry_record.entry; 795 stand_entry_ref = &entry_record.stand_entry; 796 797 match = False; 798 799 if( flagIsSet( filter, XTM_DM_FLAG_ALL ) ) 800 match = True; 801 802 /* No other flags? */ 803 if( flagIsSet( filter, ~ XTM_DM_FLAG_ALL ) ) { 804 805 /* Pick type of entry. */ 806 if( flagIsSet( filter, XTM_DM_FLAG_APPOINTMENTS ) && 807 entry_ref -> entry_type == XTM_DB_DAY_ENTRY ) 808 match = True; 809 810 if( flagIsSet( filter, XTM_DM_FLAG_NOTES ) && 811 entry_ref -> entry_type == XTM_DB_DAY_NOTE ) 812 match = True; 813 814 815 /* Pick out all specialities. */ 816 if( flagIsSet( filter, XTM_DM_FLAG_PRIVATE ) && 817 flagIsClear( entry_ref -> flags, XTM_DB_FLAG_PRIVATE ) ) 818 match = False; 819 820 if( flagIsSet( filter, XTM_DM_FLAG_IMPORTANT ) && 821 flagIsClear( entry_ref -> flags, XTM_DB_FLAG_IMPORTANT ) ) 822 match = False; 823 824 if( flagIsSet( filter, XTM_DM_FLAG_ALARMS ) && 825 flagIsClear( entry_ref -> flags, XTM_DB_FLAG_ALARM ) ) 826 match = False; 827 828 if( flagIsSet( filter, XTM_DM_FLAG_REPEATED ) && 829 entry_ref -> entry_category != XTM_DB_REP_ENTRY_LIST ) 830 match = False; 831 832 if( flagIsSet( filter, XTM_DM_FLAG_STICKY ) && 833 entry_ref -> entry_category != XTM_DB_STICKY_LIST ) 834 match = False; 835 836 if( entry_ref -> entry_type == XTM_DB_DAY_NOTE ) { 837 if( flagIsSet( filter, XTM_DM_FLAG_DONE ) && 838 flagIsClear( filter, XTM_DM_FLAG_NOT_DONE ) && 839 flagIsClear( entry_ref -> flags, XTM_DB_FLAG_NOTE_DONE ) ) 840 match = False; 841 842 if( flagIsSet( filter, XTM_DM_FLAG_NOT_DONE ) && 843 flagIsClear( filter, XTM_DM_FLAG_DONE ) && 844 flagIsSet( entry_ref -> flags, XTM_DB_FLAG_NOTE_DONE ) ) 845 match = False; 846 } 847 848 849 /* Search in the entry text? */ 850 if( match && flagIsSet( filter, XTM_DM_FLAG_SEARCH_TEXT ) ) { 851 case_sens = flagIsSet( filter, XTM_DM_FLAG_TEXT_CASE_SENS ); 852 853 if( entry_record.all_text != NULL ) 854 match = searchString( filter_ref -> text_string, True, 855 entry_record.all_text, case_sens ); 856 else 857 match = searchString( filter_ref -> text_string, True, 858 entry_ref -> text, case_sens ); 859 } 860 861 /* Search the tag? */ 862 if( match && flagIsSet( filter, XTM_DM_FLAG_SEARCH_TAG ) ) { 863 case_sens = flagIsSet( filter, XTM_DM_FLAG_TAG_CASE_SENS ); 864 865 if( entry_ref -> tag[ 0 ] != '\0' ) 866 match = searchString( entry_ref -> tag, case_sens, 867 filter_ref -> tag_string, True ); 868 else 869 match = False; 870 } 871 872 } /* if */ 873 874 875 /* If there is a match, save the entry in the match list. */ 876 if( match ) { 877 878 /* The original will be freed when we delete list. */ 879 if( entry_record.all_text != NULL ) { 880 char_ref = SysNewString( entry_record.all_text ); 881 882 entry_record.all_text = char_ref; 883 } 884 885 /* Notes are inserted first in the day. */ 886 if( entry_record.entry.entry_type == XTM_DB_DAY_NOTE ) 887 entry_record.entry.time_stamp = 0; 888 889 entry_record.entry.date_stamp = current_date; 890 891 /* Insert the entry in the appointments list. */ 892 lst_status = LstLinkSearchFirst( 893 entries, 894 &entry_record, 895 (EQUALS_FUNC_TYPE) entrySortFunc ); 896 897 if( lst_status == LST_OK ) 898 lst_status = LstLinkInsertCurrent( entries, 899 &entry_record ); 900 else 901 lst_status = LstLinkInsertLast( entries, 902 &entry_record ); 903 904 } /* if */ 905 906 907 /* Next record. */ 908 lst_status = LstLinkCurrentNext( list_ref[ index ] ); 909 910 } /* while */ 911 912 } /* if */ 913 914 /* Delete the database list. */ 915 xtmDmDeleteEntriesList( list_ref[ index ] ); 916 917 } /* loop */ 918 919 920 /* Did the user press the cancel button? */ 921 if( workW != NULL ) { 922 if( xitBusyDialogCancelled( workW, context ) ) { 923 xtmDbCloseEntryDb( &database ); 924 925 return( XTM_DB_ERROR ); 926 } 927 } 928 929 /* The next day. */ 930 TimAddDays( ¤t_date, 1 ); 931 932 } /* while */ 933 934 xtmDbCloseEntryDb( &database ); 935 936 937 return( XTM_DB_OK ); 938 939 } /* fetchFilteredEntriesDay */ 940 941 942 /*----------------------------------------------------------------------*/ 943 944 static Boolean searchString(char * search_string,Boolean case_sens1,char * in_string,Boolean case_sens2)945 searchString( char *search_string, 946 Boolean case_sens1, 947 char *in_string, 948 Boolean case_sens2 ) 949 { 950 951 /* Variables. */ 952 char *char_ref; 953 char *new_in_string; 954 char *new_search_string; 955 956 /* Code. */ 957 958 new_search_string = SysNewString( search_string ); 959 new_in_string = SysNewString( in_string ); 960 961 962 /* Convert to uppercase if not case sensitive. */ 963 if( ! case_sens1 ) { 964 char_ref = new_search_string; 965 966 while( *char_ref != '\0' ) { 967 *char_ref = toupper( *char_ref ); 968 char_ref++; 969 } 970 } 971 972 if( ! case_sens2 ) { 973 char_ref = new_in_string; 974 975 while( *char_ref != '\0' ) { 976 *char_ref = toupper( *char_ref ); 977 char_ref++; 978 } 979 } 980 981 /* Search the string. */ 982 char_ref = strstr( new_in_string, new_search_string ); 983 984 SysFree( new_search_string ); 985 SysFree( new_in_string ); 986 987 if( char_ref == NULL ) 988 return( False ); 989 990 991 return( True ); 992 993 } /* searchString */ 994