static void LoadPreferencesNoahPro(AppContext* appContext) { DmOpenRef db; UInt recNo; void * recData; MemHandle recHandle; UInt recsCount; Boolean fRecFound = false; appContext->fFirstRun = true; db = DmOpenDatabaseByTypeCreator(NOAH_PREF_TYPE, NOAH_PRO_CREATOR, dmModeReadWrite); if (!db) return; recsCount = DmNumRecords(db); for (recNo = 0; (recNo < recsCount) && !fRecFound; recNo++) { recHandle = DmQueryRecord(db, recNo); recData = MemHandleLock(recHandle); if ( (MemHandleSize(recHandle)>=PREF_REC_MIN_SIZE) && IsValidPrefRecord( recData ) ) { LogG( "LoadPreferencesNoahPro(), found prefs record" ); fRecFound = true; appContext->fFirstRun = false; DeserializePreferencesNoahPro(appContext, (unsigned char*)recData, MemHandleSize(recHandle) ); } MemPtrUnlock(recData); } DmCloseDatabase(db); }
/* Delete a bookmark for a given word in a bookmark database indicated by sortType */ static Err DeleteBookmarkInDB(AppContext* appContext, BookmarkSortType sortType, char *word) { Err err; UInt16 recsCount, i; MemHandle recHandle; char * wordInRecord; err = OpenBookmarksDB(appContext, sortType); if ( errNone != err ) return err; recsCount = DmNumRecords(appContext->bookmarksDb); for (i = 0; i < recsCount; i++) { recHandle = DmQueryRecord(appContext->bookmarksDb, i); if (!recHandle) { err = DmGetLastErr(); goto OnError; } wordInRecord = (char*)MemHandleLock(recHandle); Assert(wordInRecord); if (0 == StrCompare(wordInRecord, word)) { MemHandleUnlock(recHandle); DmRemoveRecord(appContext->bookmarksDb, i); break; } MemHandleUnlock(recHandle); } OnError: CloseBookmarksDB(appContext); return err; }
// Open preferences database and find a record that contains preferences. // Return errNone if opened succesfully, otherwise an error: // psErrNoPrefDatabase - pref database couldn't be found // devnote: it scans through all records even though we only store preferences // in one record because I want to be able to use preferences database used // in earlier versions of Noah Pro/Thes. Err PrefsStoreReader::ErrOpenPrefsDatabase() { if (_db) { Assert(_recHandle); Assert(_recData); return errNone; } // we already tried to open the database but couldn't, so don't try again if (_fDbNotFound) return psErrNoPrefDatabase; LocalID dbId; Err err = ErrFindDatabaseByNameTypeCreator(_dbName, _dbType, _dbCreator, &dbId); if (dmErrCantFind==err) { err = psErrNoPrefDatabase; goto ExitAndMarkNotFound; } if (err) goto ExitAndMarkNotFound; Assert(0!=dbId); _db = DmOpenDatabase(0, dbId, dmModeReadWrite); if (!_db) { err = DmGetLastErr(); Assert(err); goto ExitAndMarkNotFound; } UInt16 recsCount = DmNumRecords(_db); for (UInt16 recNo = 0; recNo < recsCount; recNo++) { _recHandle = DmQueryRecord(_db, recNo); _recData = (unsigned char*)MemHandleLock(_recHandle); if ( (MemHandleSize(_recHandle)>=4) && FValidPrefsStoreRecord(_recData) ) { // we found the record with prefernces so remember _recData and _recHandle // those must be freed in destructor return errNone; } MemHandleUnlock(_recHandle); _recHandle = NULL; } DmCloseDatabase(_db); _db = 0; err = psErrNoPrefDatabase; ExitAndMarkNotFound: _fDbNotFound = true; return err; }
void Memo_WriteOpen(void) { if (s_pMemoDb) return; s_pMemoDb = DmOpenDatabaseByTypeCreator('DATA', sysFileCMemo, dmModeReadWrite); if(!s_pMemoDb) return; s_iRecNum = DmNumRecords(s_pMemoDb); s_RecHandle = DmNewRecord(s_pMemoDb, &s_iRecNum, diAllocSize); s_iOffset = 0; s_iAllocSize = diAllocSize; }
static void CreateRemoveList( void ) /* THROWS */ { UInt16 i; /* create list for documents that have been deleted since the last session */ removeListSize = DmNumRecords( plkrDocList ); if ( removeListSize != 0 ) { removeList = SafeMemPtrNew( removeListSize * sizeof *removeList ); for ( i = 0; i < removeListSize; i++) removeList[ i ] = true; } }
/* Note: You must release the record when done, e.g., by using CloseRecord() */ MemHandle FindDocData ( Char* name, /* document name to search for */ UInt16 numOfElements, /* number of elements to search, set to ALL_ELEMENTS to search all elements */ UInt16* index /* upon successful return, the index of the record, pass NULL for this parameter if you don't want to retrieve this value */ ) /* THROWS */ { THROW_IF( plkrDocList == NULL, dmErrNoOpenDatabase ); THROW_IF( name == NULL, dmErrInvalidParam ); if ( numOfElements == ALL_ELEMENTS ) numOfElements = DmNumRecords( plkrDocList ); return SearchRAMDocument( plkrDocList, CompareNames, name, numOfElements, index ); }
static void ProcessXlitDB ( UInt16 cardNo, LocalID dbID ) { UInt16 numRecords; UInt16 i; DmOpenRef dbRef; dbRef = DmOpenDatabase( cardNo, dbID, dmModeReadOnly ); if ( dbRef == NULL ) return; numRecords = DmNumRecords( dbRef ); for ( i = 0 ; i < numRecords ; i++ ) { MemHandle handle; handle = DmGetRecord( dbRef, i ); if ( handle != NULL ) { XlitEntry* entry; entry = SafeMemPtrNew( sizeof( XlitEntry ) ); entry->dbRef = dbRef; entry->index = i; entry->handle = handle; entry->header = MemHandleLock( handle ); ListAppend( xlitDataList, entry ); numXlits++; } } }
/* Return the number of bookmarked words */ static UInt16 BookmarksWordCount(AppContext* appContext) { Assert(appContext->bookmarksDb); return DmNumRecords(appContext->bookmarksDb); }
/*********************************************************************** * * FUNCTION: ThumbnailViewHandleEvent * * DESCRIPTION: This routine is the event handler for the "Thumbnail View" * of the Record application. * * PARAMETERS: event - a pointer to an EventType structure * * RETURNED: true if the event was handled and should not be passed * to a higher level handler. * ***********************************************************************/ Boolean ThumbnailViewHandleEvent (EventPtr event) { FormPtr frm = NULL; Boolean handled = false; switch (event->eType) { case keyDownEvent: /* Hardware button pressed? */ if (TxtCharIsHardKey(event->data.keyDown.modifiers, event->data.keyDown.chr)) { if (!(event->data.keyDown.modifiers & poweredOnKeyMask)) ThumbnailViewNextCategory(); handled = true; } else if (EvtKeydownIsVirtual(event)) { switch (event->data.keyDown.chr) { case vchrPageUp: case vchrRockerUp: if (d.fiveWayNavigation) { /* Deselect previous item */ ToggleButton(d.thumbnailX, d.thumbnailY, false); /* Select new item, scroll if necessary */ if (ThumbnailViewMoveCursorUp()) ThumbnailViewScroll(-1); UpdateButtonAndIndex(); } else { ThumbnailViewPageScroll(winUp); } handled = true; break; case vchrPageDown: case vchrRockerDown: if (d.fiveWayNavigation) { /* Deselect previous item */ ToggleButton(d.thumbnailX, d.thumbnailY, false); /* Select new item, scroll if necessary */ if (ThumbnailViewMoveCursorDown()) ThumbnailViewScroll(1); UpdateButtonAndIndex(); } else { ThumbnailViewPageScroll(winDown); } handled = true; break; /* Treo 600 5-way navigation */ case vchrRockerCenter: handled = ThumbnailViewHandleFiveWayNavSelect(); break; case vchrRockerLeft: handled = ThumbnailViewHandleFiveWayNavLeft(); break; case vchrRockerRight: handled = ThumbnailViewHandleFiveWayNavRight(); break; /* Tungsten 5-way navigation */ case vchrNavChange: if (NavDirectionPressed(event, Left)) handled = ThumbnailViewHandleFiveWayNavLeft(); else if (NavDirectionPressed(event, Right)) handled = ThumbnailViewHandleFiveWayNavRight(); else if (NavSelectPressed(event)) handled = ThumbnailViewHandleFiveWayNavSelect(); break; /* case vchrSendData: */ /* ThumbnailViewDoCommand(ThumbnailRecordBeamCategoryCmd); */ /* handled = true; */ /* break; */ default: /* ignore */ } } break; case ctlSelectEvent: switch (event->data.ctlSelect.controlID) { case NewButton: /* Create new sketch after all existing ones */ p.dbI = DmNumRecords(d.dbR); AllocImage(); FrmGotoForm(p.flags & PFLAGS_WITH_TITLEBAR ? DiddleTForm : DiddleForm); handled = true; break; case CategoryPop: ThumbnailViewSelectCategory(); handled = true; break; case TextListButton: FrmGotoForm(DiddleListForm); handled = true; break; case ThumbnailDetailListButton: FrmGotoForm(DiddleThumbnailDetailForm); handled = true; break; } break; case frmGotoEvent: p.dbI = event->data.frmGoto.recordNum; SwitchCategoryForGoto(); FrmGotoForm(p.flags & PFLAGS_WITH_TITLEBAR ? DiddleTForm : DiddleForm); event->eType = dbOpenRecordFieldEvent; EvtAddEventToQueue(event); handled = true; break; case menuEvent: { Char chr = 0; switch(event->data.menu.itemID) { case menuitemID_CmdAbout: DoAboutDialog(); handled = true; break; case menuitemID_CmdSecurity: ThumbnailDoCmdSecurity(); handled = true; break; case menuitemID_CmdSortByAlarm: case menuitemID_CmdSortByName: if (event->data.menu.itemID == menuitemID_CmdSortByAlarm) DmInsertionSort(d.dbR, &SortByAlarmTime, 0); else DmInsertionSort(d.dbR, &SortByName, 0); SetTopVisibleRecord(0); ThumbnailViewLoadRecords(FrmGetActiveForm()); handled = true; break; case menuitemID_CmdPref: chr=cmdPref; break; case menuitemID_CmdExtPref: chr=cmdExtPref; break; case menuitemID_CmdHWPref: chr=cmdHWPref; break; case menuitemID_CmdAlarmPref: chr=cmdAlarmPref; break; case menuitemID_CmdHelp: chr=cmdHelp; break; } if (!handled) handled = KeyDown(chr); } break; case frmOpenEvent: frm = FrmGetActiveForm(); ThumbnailViewInit(frm); FrmDrawForm(frm); /* Disable 5-way navigation initially */ d.fiveWayNavigation = false; /* Clean up */ if (d.record_name) MemHandleFree(d.record_name); d.record_name = NULL; if (d.record_note) MemHandleFree(d.record_note); d.record_note = NULL; handled = true; break; case frmUpdateEvent: handled = ThumbnailViewUpdateDisplay(event->data.frmUpdate.updateCode); break; case menuCmdBarOpenEvent: MenuCmdBarAddButton(menuCmdBarOnLeft, BarSecureBitmap, menuCmdBarResultMenuItem, menuitemID_CmdSecurity, 0); /* Tell the field package to not add buttons automatically; */ /* we've done it all ourselves. */ event->data.menuCmdBarOpen.preventFieldButtons = true; /* don't set handled to true; this event must fall through to the system. */ break; case sclRepeatEvent: ThumbnailViewScroll (event->data.sclRepeat.newValue - event->data.sclRepeat.value); break; case dbNonKeyCommandEvent: handled = HandleNonKeyCommandCode(event->data.menu.itemID); break; /* case frmObjectFocusTakeEvent: */ /* { */ /* RectangleType r; */ /* FormType* frm = FrmGetFormPtr(event->data.frmObjectFocusTake.formID); */ /* const UInt16 id = event->data.frmObjectFocusTake.objectID; */ /* const UInt16 idx = FrmGetObjectIndex(frm, id); */ /* if (id >= Thumb1 && id <= Thumb30) { */ /* FrmGetObjectBounds(frm, idx, &r); */ /* FrmSetFocus(frm, idx); */ /* HsNavDrawFocusRing(frm, id, hsNavFocusRingNoExtraInfo, &r, */ /* hsNavFocusRingStyleObjectTypeDefault, false); */ /* handled = true; */ /* } */ /* } */ /* break; */ default: /* do nothing */ } return handled; }
/************************************************************ * * FUNCTION: ApptChangeRecord * * DESCRIPTION: Change a record in the Appointment Database * * PARAMETERS: database pointer * database index * database record * changed fields * * RETURNS: ##0 if successful, errorcode if not * * CREATED: 1/25/95 * * BY: Roger Flores * * COMMENTS: Records are not stored with extra padding - they * are always resized to their exact storage space. This avoids * a database compression issue. The code works as follows: * * 1) get the size of the new record * 2) make the new record * 3) pack the packed record plus the changes into the new record * 4) if the sort position is changes move to the new position * 5) attach in position * *************************************************************/ Err ApptChangeRecord(DmOpenRef dbP, UInt16 *index, ApptDBRecordPtr r, ApptDBRecordFlags changedFields) { Err result; Int16 newIndex; UInt16 attributes; Boolean dontMove; MemHandle oldH; MemHandle srcH; MemHandle dstH; ApptDBRecordType src; ApptPackedDBRecordPtr dst = 0; ApptPackedDBRecordPtr cmp; // We do not assume that r is completely valid so we get a valid // ApptDBRecordPtr... if ((result = ApptGetRecord(dbP, *index, &src, &srcH)) != 0) return result; // and we apply the changes to it. if (changedFields.when) src.when = r->when; if (changedFields.alarm) src.alarm = r->alarm; if (changedFields.repeat) src.repeat = r->repeat; if (changedFields.exceptions) src.exceptions = r->exceptions; if (changedFields.description) src.description = r->description; if (changedFields.note) src.note = r->note; // Allocate a new chunk with the correct size and pack the data from // the unpacked record into it. dstH = DmNewHandle(dbP, (UInt32) ApptPackedSize(&src)); if (dstH) { dst = MemHandleLock (dstH); ApptPack (&src, dst); } MemHandleUnlock (srcH); if (dstH == NULL) return dmErrMemError; // If the sort position is changed move to the new position. // Check if any of the key fields have changed. if ((!changedFields.when) && (! changedFields.repeat)) goto attachRecord; // repeating events aren't in sorted order // Make sure *index-1 < *index < *index+1, if so it's in sorted // order. Leave it there. if (*index > 0) { // This record wasn't deleted and deleted records are at the end of the // database so the prior record may not be deleted! cmp = MemHandleLock (DmQueryRecord(dbP, *index-1)); dontMove = (ApptComparePackedRecords (cmp, dst, 0, NULL, NULL, 0) <= 0); MemPtrUnlock (cmp); } else dontMove = true; if (dontMove && (*index+1 < DmNumRecords (dbP))) { DmRecordInfo(dbP, *index+1, &attributes, NULL, NULL); if ( ! (attributes & dmRecAttrDelete) ) { cmp = MemHandleLock (DmQueryRecord(dbP, *index+1)); dontMove &= (ApptComparePackedRecords (dst, cmp, 0, NULL, NULL, 0) <= 0); MemPtrUnlock (cmp); } } if (dontMove) goto attachRecord; // The record isn't in the right position. Move it. newIndex = ApptFindSortPosition (dbP, dst); DmMoveRecord (dbP, *index, newIndex); if (newIndex > *index) newIndex--; *index = newIndex; // return new position attachRecord: // Attach the new record to the old index, the preserves the // category and record id. result = DmAttachRecord (dbP, index, dstH, &oldH); MemPtrUnlock(dst); if (result) return result; MemHandleFree(oldH); return 0; }
/*********************************************************************** * * 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); }
UInt32 ApptAlarmMunger ( DmOpenRef inDbR, UInt32 inAlarmStart, UInt32 inAlarmStop, PendingAlarmQueueType * inAlarmInternalsP, UInt16* ioCountP, DatebookAlarmType * outAlarmListP, Boolean* outAudibleP ) { UInt16 alarmListSize; UInt16 baseIndex = 0; UInt16 numRecords; UInt16 numAlarms = 0; UInt16 recordNum; MemHandle recordH; ApptDBRecordType apptRec; ApptPackedDBRecordPtr r; UInt32 alarmTime; UInt32 earliestAlarm = 0; UInt32 uniqueID; Boolean skip; UInt16 i; UInt16 index; UInt16 dismissedCount = 0; UInt32 * dismissedListP = 0; if ( outAudibleP ) { *outAudibleP = false; } if ( ioCountP ) { alarmListSize = *ioCountP; } else { alarmListSize = 0; } if (inAlarmInternalsP) { dismissedCount = GetDismissedAlarmCount (inAlarmInternalsP); dismissedListP = GetDismissedAlarmList (inAlarmInternalsP); } numRecords = DmNumRecords (inDbR); for (recordNum = 0; recordNum < numRecords; recordNum++) { recordH = DmQueryRecord (inDbR, recordNum); DmRecordInfo (inDbR, recordNum, NULL, &uniqueID, NULL); if ( !recordH ) { break; } r = (ApptPackedDBRecordPtr) MemHandleLock (recordH); if ( r->flags.alarm ) { ApptUnpack (r, &apptRec); // Get the first alarm on or after inAlarmStart alarmTime = ApptGetAlarmTime (&apptRec, inAlarmStart); // If in range, add the alarm to the output if ( alarmTime && (alarmTime >= inAlarmStart) && (alarmTime <= inAlarmStop) ) { skip = false; index = numAlarms; if (inAlarmInternalsP) { // If this alarm was snoozed, make room for it at the front of the list if (uniqueID == inAlarmInternalsP->snoozeAnchorUniqueID) { // If the list is already full, don't bother shifting its contents. // The snoozed alarm will overwrite the oldest alarm, which is at // the front of the list. // If the list is empty, there's nothing to shift. if (outAlarmListP && (index != 0) && (index != alarmListSize)) { MemMove (&outAlarmListP[1], &outAlarmListP[0], (alarmListSize - 1) * sizeof(*outAlarmListP) ); } // The snoozed alarm is placed at the front of the list index = 0; // Protect the snoozed alarm from being pushed out of a full list baseIndex = 1; } // Otherwise, skip over any alarms that have already been dismissed else if (dismissedCount && (alarmTime == inAlarmStart)) { for (i = 0; i < dismissedCount; i++) { if (dismissedListP [i] == uniqueID) { skip = true; break; } } } } if (!skip) { // If collecting alarms, add it to the list if (outAlarmListP) { // If the alarm list is too large, push the oldest alarm off of the // queue to make room for the new one if (index >= alarmListSize) { // baseIndex is usually 0, but will be set to 1 while snoozing to // keep the snoozed alarm from being pushed out of the queue MemMove (&outAlarmListP[baseIndex], &outAlarmListP[baseIndex + 1], (alarmListSize - baseIndex - 1) * sizeof(*outAlarmListP) ); index = alarmListSize - 1; } outAlarmListP[index].recordNum = recordNum; outAlarmListP[index].alarmTime = alarmTime; } // If the event is timed, inform the caller to play the alarm sound if (outAudibleP && (TimeToInt (apptRec.when->startTime) != apptNoTime) ) { *outAudibleP = true; } // Remember the earliest in-range alarm for our return value if ( (alarmTime < earliestAlarm) || (earliestAlarm == 0) ) { earliestAlarm = alarmTime; } numAlarms++; } // don't skip this alarm } // add alarm to output } // an alarm exists MemHandleUnlock (recordH); } if (ioCountP) { *ioCountP = numAlarms; } return earliestAlarm; }
/***************************************************************************** * Function: GadgetDrawHintCurrent * * Description: Draw hint for current gTimeIndex if needed (may be forced NOT * to draw with GadgetSetNeedsRedraw(false)); *****************************************************************************/ void GadgetDrawHintCurrent(void) { Char *tmp, *bot, begin[timeStringLength], end[timeStringLength], *day; MemHandle mc, mt, mh, type; CourseDBRecord c; TimeDBRecord *tc; RectangleType rect, bounds; UInt16 gadgetIndex = FrmGetObjectIndex(gForm, gGadgetID); RGBColorType color, prevColor; UInt16 attr; // Need to check that due to damn f*** DmRecordInfo which will show a // fatal alert when called on non-existing record (this happens for example // right after creating the new database... if ((gTimeIndex >= DmNumRecords(DatabaseGetRef())) || (gCourseIndex >= DmNumRecords(DatabaseGetRef())) ) return; if (gHintDrawn) { // Delete border around previous entry if ( (gTimeDrawnIndex < DmNumRecords(DatabaseGetRef())) && (DmRecordInfo(DatabaseGetRef(), gTimeDrawnIndex, &attr, NULL, NULL) == errNone) ) { attr &= dmRecAttrCategoryMask; if (attr == DatabaseGetCat()) { mt = DmQueryRecord(DatabaseGetRef(), gTimeDrawnIndex); if (mt) { // mt may be null, for example if next is drawn after delete! tc = (TimeDBRecord *)MemHandleLock(mt); if ((tc->type == TYPE_TIME) && GadgetEventIsVisible(tc) ) { TNlist *tmpl = gGadgetTimeList; GadgetTimeListType *gtl = NULL; while (tmpl != NULL) { gtl = tmpl->data; if (gtl->index == gTimeDrawnIndex) { break; } tmpl = tmpl->next; } color.r=tc->color[0]; color.g=tc->color[1]; color.b=tc->color[2]; if (gPrefs.showTimeline) GadgetDrawTimeline(gtErase); if (gtl != NULL) { GadgetDrawTime(tc->begin, tc->end, tc->day, &color, tc->course, gtl->num, gtl->pos); } if (gPrefs.showTimeline) GadgetDrawTimeline(gtDraw); } MemHandleUnlock(mt); } } } } gTimeDrawnIndex=gTimeIndex; gHintDrawn=true; if (DmRecordInfo(DatabaseGetRef(), gCourseIndex, &attr, NULL, NULL) == errNone) { attr &= dmRecAttrCategoryMask; if (attr == DatabaseGetCat()) { // Record is in currently displayed category mc = DmQueryRecord(DatabaseGetRef(), gCourseIndex); if (! mc) return; mt = DmQueryRecord(DatabaseGetRef(), gTimeIndex); if (! mt) return; UnpackCourse(&c, MemHandleLock(mc)); tc = (TimeDBRecord *)MemHandleLock(mt); if ( GadgetEventIsVisible(tc) ) { TNlist *tmpl = gGadgetTimeList; GadgetTimeListType *gtl = NULL; while (tmpl != NULL) { gtl = tmpl->data; if (gtl->index == gTimeDrawnIndex) { break; } tmpl = tmpl->next; } mh = DmGetResource(strRsc, GADGET_STRINGS_WDAYSTART+tc->day); day = (Char *)MemHandleLock(mh); // Lecture Name (Teacher) [Typ] tmp=(Char *)MemPtrNew(StrLen(c.name)+StrLen(c.teacherName)+4+3+CTYPE_SHORT_MAXLENGTH); MemSet(tmp, MemPtrSize(tmp), 0); type = MemHandleNew(1); CourseTypeGetShort(&type, c.ctype); StrPrintF(tmp, "%s (%s) [%s]", c.name, c.teacherName, (Char *)MemHandleLock(type)); MemHandleUnlock(type); MemHandleFree(type); // Fr 08:00 - 09:30 (Room) <-- Example // 3 5 3 5 3+StrLen(room) <-- Num Chars for MemPtrNew bot=(Char *)MemPtrNew(20+sizeof(tc->room)+MemPtrSize(day)); MemSet(bot, MemPtrSize(bot), 0); TimeToAscii(tc->begin.hours, tc->begin.minutes, GadgetGetTimeFormat(), begin); TimeToAscii(tc->end.hours, tc->end.minutes, GadgetGetTimeFormat(), end); mh = DmGetResource(strRsc, GADGET_STRINGS_WDAYSTART+tc->day); StrPrintF(bot, "%s %s - %s (%s)", day, begin, end, tc->room); FrmGetObjectBounds(gForm, gadgetIndex, &bounds); if (gtl != NULL) { GadgetTimeSetRect(&rect, tc->begin, tc->end, tc->day, gtl->num, gtl->pos); RctSetRectangle(&rect, // + inset (two boxes, one black, one white) rect.topLeft.x + 2, rect.topLeft.y + 2, // width - 2 * inset rect.extent.x - 4, // height - 2 * inset rect.extent.y - 4 ); /* Invert color, looks not so nice aka bad color.r=255- tc->color[0]; color.g=255- tc->color[1]; color.b=255- tc->color[2]; */ color.r=255; color.g=255; color.b=255; TNSetForeColorRGB(&color, &prevColor); WinDrawRectangleFrame(simpleFrame, &rect); color.r=0; color.g=0; color.b=0; RctSetRectangle(&rect, rect.topLeft.x-1, rect.topLeft.y-1, rect.extent.x+2, rect.extent.y+2); TNSetForeColorRGB(&color, NULL); WinDrawRectangleFrame(simpleFrame, &rect); TNSetForeColorRGB(&prevColor, NULL); } // WinInvertRectangleFrame(simpleFrame, &rect); GadgetDrawHint(tmp, bot, tc->note); MemPtrFree((MemPtr) tmp); MemPtrFree((MemPtr) bot); MemHandleUnlock(mh); } else { MemHandleUnlock(mc); MemHandleUnlock(mt); GadgetDrawHintNext(); return; } MemHandleUnlock(mc); MemHandleUnlock(mt); } // End attr == current category } }
// Save preferences previously set via ErrSet*() calls to a database. // If something goes wrong, returns an error // Possible errors: // memErrNotEnoughSpace - not enough memory to allocate needed structures // errors from Dm*() calls Err PrefsStoreWriter::ErrSavePreferences() { Err err = errNone; long blobSize; void * prefsBlob = SerializeItems(_items, _itemsCount, &blobSize); if ( NULL == prefsBlob ) return memErrNotEnoughSpace; DmOpenRef db = DmOpenDatabaseByTypeCreator(_dbType, _dbCreator, dmModeReadWrite); if (!db) { err = DmCreateDatabase(0, _dbName, _dbCreator, _dbType, false); if ( err) return err; db = DmOpenDatabaseByTypeCreator(_dbType, _dbCreator, dmModeReadWrite); if (!db) return DmGetLastErr(); } // set backup bit on the database. code adapted from DataStore.cpp // DataStore::open() if (errNone == err) { LocalID localId; UInt16 cardNo; UInt16 attribs; err = DmOpenDatabaseInfo(db, &localId, NULL, NULL, &cardNo, NULL); if (errNone != err) goto Continue; err = DmDatabaseInfo(cardNo, localId, NULL, &attribs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (errNone != err) goto Continue; if (0 != attribs & dmHdrAttrBackup) goto Continue; attribs |= dmHdrAttrBackup; err = DmSetDatabaseInfo(cardNo, localId, NULL, &attribs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); Continue: err = errNone; } UInt16 recNo = 0; UInt16 recsCount = DmNumRecords(db); MemHandle recHandle; Boolean fRecordBusy = false; Boolean fRecFound = false; void * recData; long recSize; while (recNo < recsCount) { recHandle = DmGetRecord(db, recNo); fRecordBusy = true; recData = MemHandleLock(recHandle); recSize = MemHandleSize(recHandle); if (IsValidPrefRecord(recData)) { fRecFound = true; break; } MemPtrUnlock(recData); DmReleaseRecord(db, recNo, true); fRecordBusy = false; ++recNo; } if (fRecFound && blobSize>recSize) { /* need to resize the record */ MemPtrUnlock(recData); DmReleaseRecord(db,recNo,true); fRecordBusy = false; recHandle = DmResizeRecord(db, recNo, blobSize); if ( NULL == recHandle ) return DmGetLastErr(); recData = MemHandleLock(recHandle); Assert( MemHandleSize(recHandle) == blobSize ); } if (!fRecFound) { recNo = 0; recHandle = DmNewRecord(db, &recNo, blobSize); if (!recHandle) { err = DmGetLastErr(); goto CloseDbExit; } recData = MemHandleLock(recHandle); fRecordBusy = true; } err = DmWrite(recData, 0, prefsBlob, blobSize); MemPtrUnlock(recData); if (fRecordBusy) DmReleaseRecord(db, recNo, true); CloseDbExit: // if had error before - preserve that error // otherwise return error code from DmCloseDatabase() if (err) DmCloseDatabase(db); else err = DmCloseDatabase(db); new_free( prefsBlob ); return err; }
/** * @brief Read the happydays information from address db, and insert into Happydays DB * @param frm StartForm to display indicator bars * @return If success, return true, or return false */ Boolean NewUpdateHappyDaysDB(FormPtr frm) { UInt16 currIndex = 0; PrvAddrPackedDBRecord *rp; AddrDBRecordType r; MemHandle recordH = 0; UInt16 recordNum; int i = 0, indicateNext; int step; // create the happydays cache db HappyDays hd; Boolean ignore = false; // ignore error record Char* hdField; UInt16 addrattr, index; Char *p, *q, *end; Int16 err; // display collecting information // FrmDrawForm(frm); // clean up old database // CleanupHappyDaysCache(MainDB); recordNum = DmNumRecords(AddressDB); indicateNext = step = recordNum / INDICATE_NUM; if (recordNum > 50) initIndicate(); while (1) { char *name1, *name2; Int8 whichField; // birthday field or note field? recordH = DmQueryNextInCategory(AddressDB, &currIndex, dmAllCategories); if (!recordH) break; if (i++ == indicateNext) { if (recordNum > 50) displayNextIndicate( (i-1) / step); indicateNext += step; } DmRecordInfo(AddressDB, currIndex, &addrattr, NULL, NULL); addrattr &= dmRecAttrCategoryMask; // get category info rp = (PrvAddrPackedDBRecord*)MemHandleLock(recordH); /* * Build the unpacked structure for an AddressDB record. It * is just a bunch of pointers into the rp structure. */ NewAddrUnpack(rp, &r); if ( (gHappyDaysField <= 0 || !r.fields[gHappyDaysField]) // there is no birthday info(trick. should check flags, but I think it is ok) // && DateToInt(r.birthdayInfo.birthdayDate) == 0 && !(gPrefsR.scannote && r.fields[note] && StrStr(r.fields[note], gPrefsR.notifywith) ) ) { // If there is not exist Happydays field or note field, or internal birthday field(in NEW PIMS) // MemHandleUnlock(recordH); currIndex++; continue; } MemSet(&hd, sizeof(hd), 0); hd.addrRecordNum = currIndex; if (DetermineRecordName(&r, gSortByCompany, &hd.name1, &hd.name2)) { // name 1 has priority; hd.flag.bits.priority_name1 = 1; } // =========================================================== // Process Birthday field first // =========================================================== if (DateToInt(r.birthdayInfo.birthdayDate) != 0) { hd.date = r.birthdayInfo.birthdayDate; hd.flag.bits.year = 1; hd.flag.bits.solar = 1; // maintain address book order(name order) // list order is determined by sort err = HDNewRecord(MainDB, &hd, &index); if (!err) { UInt16 attr; // set the category of the new record to the category // it belongs in DmRecordInfo(MainDB, index, &attr, NULL, NULL); attr &= ~dmRecAttrCategoryMask; attr |= addrattr; DmSetRecordInfo(MainDB, index, &attr, NULL); DmReleaseRecord(MainDB, index, true); } } // =========================================================== // save the temporary name name1 = hd.name1; name2 = hd.name2; if (gHappyDaysField >= 0 && r.fields[gHappyDaysField]) { whichField = gHappyDaysField; } else if (gPrefsR.scannote // scanNote & exists && r.fields[note] && StrStr(r.fields[note], gPrefsR.notifywith)) { whichField = note; } else whichField = -1; while (whichField >= 0) { if (whichField == note) { p = StrStr(r.fields[note], gPrefsR.notifywith) + StrLen(gPrefsR.notifywith) + 1; if ( StrLen(r.fields[note]) < (p - r.fields[note]) ) break; } else { p = r.fields[whichField]; } hdField = MemPtrNew(StrLen(r.fields[whichField]) - (p - r.fields[whichField])+1); SysCopyStringResource(gAppErrStr, NotEnoughMemoryString); ErrFatalDisplayIf(!hdField, gAppErrStr); p = StrCopy(hdField, p); if (whichField == note && (end = StrStr(p, gPrefsR.notifywith))) { // end delimeter // *end = 0; } while ((q = StrChr(p, '\n'))) { // multiple event // *q = 0; if (AnalizeOneRecord(addrattr, p, &hd, &ignore)) goto Update_ErrHandler; p = q+1; // restore the saved name hd.name1 = name1; hd.name2 = name2; // reset multiple flag hd.flag.bits.multiple_event = 0; while (*p == ' ' || *p == '\t' || *p == '\n') p++; // skip white space } // last record if (*p) { // check the null '\n' if (AnalizeOneRecord(addrattr, p, &hd, &ignore)) goto Update_ErrHandler; } if (whichField == gHappyDaysField // next is note field && (gPrefsR.scannote // scanNote & exists && r.fields[note] && StrStr(r.fields[note], gPrefsR.notifywith)) ) { whichField = note; } else whichField = -1; MemPtrFree(hdField); } MemHandleUnlock(recordH); currIndex++; } if (recordNum > 50) displayNextIndicate( INDICATE_NUM -1); return true; Update_ErrHandler: MemPtrFree(hdField); MemHandleUnlock(recordH); return false; }