/*********************************************************************** * * FUNCTION: ThumbnailViewLoadRecords * * DESCRIPTION: This routine loads sketches into the thumbnails view form. * * PARAMETERS: nothing * * RETURNED: nothing * ***********************************************************************/ static void ThumbnailViewLoadRecords(FormType* frm) { UInt16 recordNum; if (p.dbI != noRecordSelected) { /* Is the current record before the first visible record? */ if (d.top_visible_record > p.dbI) SetTopVisibleRecord(p.dbI - DmPositionInCategory(d.dbR, p.dbI, p.category) % recordsPerRow); /* Is the current record after the last visible record? */ else { recordNum = d.top_visible_record; DmSeekRecordInCategory(d.dbR, &recordNum, DmPositionInCategory(d.dbR, p.dbI, p.category) % recordsPerRow, dmSeekForward, p.category); if (recordNum < p.dbI) SetTopVisibleRecord(p.dbI - DmPositionInCategory(d.dbR, p.dbI, p.category) % recordsPerRow); } } /* Make sure we show a full display of records. */ if (d.records_in_cat) { recordNum = dmMaxRecordIndex; DmSeekRecordInCategory(d.dbR, &recordNum, recordsPerPage - 1 - (recordsPerRow - d.records_in_cat % recordsPerRow) % recordsPerRow, dmSeekBackward, p.category); SetTopVisibleRecord(Min(d.top_visible_record, recordNum)); /* Ensure that the top visible record actually is part of this category */ recordNum = d.top_visible_record; DmSeekRecordInCategory(d.dbR, &recordNum, 0, dmSeekForward, p.category); d.top_visible_record = recordNum; } else SetTopVisibleRecord(0); ThumbnailViewLoadGadgets(frm); }
UInt16 CourseNewID(DmOpenRef cats, UInt16 category) { Err err=errNone; MemHandle m; UInt16 index=0,lastid=0; err = DmSeekRecordInCategory(cats, &index, 0, dmSeekForward, category); if (err != errNone) return 0; while ((m = DmQueryNextInCategory(cats, &index, category))) { Char *s = MemHandleLock(m); if (s[0] == TYPE_COURSE) { CourseDBRecord c; UnpackCourse(&c, s); if (c.id > lastid) lastid = c.id; } index += 1; MemHandleUnlock(m); } // lastid contains the last existing ID here, so return lastid+1 to get the first // non-existing one return lastid+1; }
/* ** Move the cursor down, if possible. ** ** The return value indicates whether we need to scroll down. */ static Boolean ThumbnailViewMoveCursorDown(void) { const UInt16 pos = DmPositionInCategory(d.dbR, p.dbI, p.category); if (DmGetLastErr() != errNone) abort(); /* We're already at the very end. */ if (pos + 1 == d.records_in_cat) return false; /* Just go to the last visible thumbnail if we can't move downward a full row. */ if (pos + recordsPerRow >= d.records_in_cat) { UInt16 x1, y1; /* dummy coordinates */ UInt16 dummyIndex = dmMaxRecordIndex; Err err = DmSeekRecordInCategory(d.dbR, &dummyIndex, 0, dmSeekBackward, p.category); if (err != errNone) abort(); MapIndexToCoordinates(&dummyIndex, &x1, &y1); /* Only move the cursor if we can move to a new row, otherwise do nothing. */ if (y1 != d.thumbnailY) { d.thumbnailY = y1; d.thumbnailX = x1; } /* Handle the special case that we need to scroll AND would go past the end. */ if (d.thumbnailY > numberOfRows - 1) { d.thumbnailY = numberOfRows - 1; return true; } return false; } /* Simply go down a row. */ if (d.thumbnailY < numberOfRows - 1) { ++d.thumbnailY; return false; } /* We need to scroll down. */ return true; }
/*********************************************************************** * * FUNCTION: ApptGetAppointments * * DESCRIPTION: This routine returns a list of appointments that are on * the date specified * * PARAMETERS: dbP - pointer to the database * date - date to search for * countP - number of appointments on the specified * day (returned value) * * RETURNED: handle of the appointment list (ApptInfoType) * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * art 6/15/95 Initial Revision * ***********************************************************************/ MemHandle ApptGetAppointments (DmOpenRef dbP, DateType date, UInt16 * countP) { Err error; Int16 result; Int16 count = 0; UInt16 recordNum; Boolean repeats; MemHandle recordH; MemHandle apptListH; ApptInfoPtr apptList; ApptDBRecordType apptRec; ApptPackedDBRecordPtr r; // Allocated a block to hold the appointment list. apptListH = MemHandleNew (sizeof (ApptInfoType) * apptMaxPerDay); ErrFatalDisplayIf(!apptListH, "Out of memory"); if (! apptListH) return (0); apptList = MemHandleLock (apptListH); // Find the first non-repeating appointment of the day. if (ApptFindFirst (dbP, date, &recordNum)) { while (count < apptMaxPerDay) { // Check if the appointment is on the date passed, if it is // add it to the appointment list. recordH = DmQueryRecord (dbP, recordNum); r = MemHandleLock (recordH); result = DateCompare (r->when.date, date); if (result == 0) { // Add the record to the appoitment list. apptList[count].startTime = r->when.startTime; apptList[count].endTime = r->when.endTime; apptList[count].recordNum = recordNum; count++; } MemHandleUnlock (recordH); if (result != 0) break; // Get the next record. error = DmSeekRecordInCategory (dbP, &recordNum, 1, dmSeekForward, dmAllCategories); if (error == dmErrSeekFailed) break; } } // Add the repeating appointments to the list. Repeating appointments // are stored at the beginning of the database. recordNum = 0; while (count < apptMaxPerDay) { recordH = DmQueryNextInCategory (dbP, &recordNum, dmAllCategories); if (! recordH) break; r = (ApptPackedDBRecordPtr) MemHandleLock (recordH); repeats = (r->flags.repeat != 0); if (repeats) { ApptUnpack (r, &apptRec); if (ApptRepeatsOnDate (&apptRec, date)) { // Add the record to the appoitment list. apptList[count].startTime = r->when.startTime; apptList[count].endTime = r->when.endTime; apptList[count].recordNum = recordNum; count++; } } MemHandleUnlock (recordH); // If the record has no repeating info we've reached the end of the // repeating appointments. if (! repeats) break; recordNum++; } // Sort the list by start time. // SysInsertionSort (apptList, count, sizeof (ApptInfoType), // ApptListCompare, 0L); // If there are no appointments on the specified day, free the appointment // list. if (count == 0) { MemPtrFree (apptList); apptListH = 0; } // Resize the appointment list block to release any unused space. else { MemHandleUnlock (apptListH); MemHandleResize (apptListH, count * sizeof (ApptInfoType)); } *countP = count; return (apptListH); }
/*********************************************************************** * * FUNCTION: ApptFindFirst * * DESCRIPTION: This routine finds the first appointment on the specified * day. * * PARAMETERS: dbP - pointer to the database * date - date to search for * indexP - pointer to the index of the first record on the * specified day (returned value) * * RETURNED: true if a record has found * * REVISION HISTORY: * Name Date Description * ---- ---- ----------- * art 6/15/95 Initial Revision * ***********************************************************************/ Boolean ApptFindFirst (DmOpenRef dbP, DateType date, UInt16 * indexP) { Err err; Int16 numOfRecords; Int16 kmin, probe, i; // all positions in the database. Int16 result = 0; // result of comparing two records UInt16 index; MemHandle recordH; Boolean found = false; ApptPackedDBRecordPtr r; kmin = probe = 0; numOfRecords = DmNumRecords(dbP); while (numOfRecords > 0) { i = numOfRecords >> 1; probe = kmin + i; index = probe; recordH = DmQueryNextInCategory (dbP, &index, dmAllCategories); if (recordH) { r = (ApptPackedDBRecordPtr) MemHandleLock (recordH); if (r->flags.repeat) result = 1; else result = DateCompare (date, r->when.date); MemHandleUnlock (recordH); } // If no handle, assume the record is deleted, deleted records // are greater. else result = -1; // If the date passed is less than the probe's date, keep searching. if (result < 0) numOfRecords = i; // If the date passed is greater than the probe's date, keep searching. else if (result > 0) { kmin = probe + 1; numOfRecords = numOfRecords - i - 1; } // If the records are equal find the first record on the day. else { found = true; *indexP = index; while (true) { err = DmSeekRecordInCategory (dbP, &index, 1, dmSeekBackward, dmAllCategories); if (err == dmErrSeekFailed) break; recordH = DmQueryRecord(dbP, index); r = (ApptPackedDBRecordPtr) MemHandleLock (recordH); if (r->flags.repeat) result = 1; else result = DateCompare (date, r->when.date); MemHandleUnlock (recordH); if (result != 0) break; *indexP = index; } break; } } // If that were no appointments on the specified day, return the // index of the next appointment (on a future day). if (! found) { if (result < 0) *indexP = probe; else *indexP = probe + 1; } return (found); }
/***************************************************************************** * Function: GadgetDrawStep * * Description: Helper function for GadgetTap. Highlights next of previous * event on current screen *****************************************************************************/ void GadgetDrawStep(WinDirectionType direction) { MemHandle m; UInt16 index=gTimeIndex, wantCourse=0, courseIndex=0; Boolean found=false, endLoop=false; TimeDBRecord *t=NULL; /* ASSUMPTION: We assume that the user does not have 2^16 events * in his schedule. Otherwise this can become an endless. loop. but * since I think this is a reasonable assumption I will not take any * special care for this... * If we loop to ID 2^16-1 we will surely find no record and terminate * below (m = ... == NULL) */ if ( (direction == winUp) && (index > 0) ) { while( !endLoop && (DmSeekRecordInCategory(DatabaseGetRefN(DB_MAIN), &index, 1, dmSeekBackward, DatabaseGetCat()) == errNone)) { Char *s; m = DmQueryRecord(DatabaseGetRefN(DB_MAIN), index); s=MemHandleLock(m); if (s[0] == TYPE_TIME) { t = (TimeDBRecord *)s; if ( GadgetEventIsVisible(t) ) { // Found entry endLoop=true; found = true; wantCourse = t->course; } } else { // nothing more to search and nothing found endLoop=true; } MemHandleUnlock(m); } } else if (direction == winDown) { index += 1; while( !endLoop && ((m = DmQueryNextInCategory(DatabaseGetRef(), &index, DatabaseGetCat())) != NULL)) { Char *s=MemHandleLock(m); if (s[0] == TYPE_TIME) { t = (TimeDBRecord *)s; if ( GadgetEventIsVisible(t) ) { // Found entry endLoop=true; found = true; wantCourse = t->course; } else { // previous in DB is not visible, search further index += 1; } } else { // nothing more to search and nothing found endLoop=true; } MemHandleUnlock(m); } } if (found && CourseGetIndex(DatabaseGetRef(), DatabaseGetCat(), wantCourse, &courseIndex)) { GadgetSetHintCourseIndex(courseIndex); GadgetSetHintTimeIndex(index); GadgetDrawHintCurrent(); } }