📄 keyedit.c
字号:
if (!Unlock_GetKey(false, NULL)) { /* We leave the edit form */ FrmGotoForm(ListForm); return; } Record_Free(gRecord); KeyEdit_FreeFields(); if (gKeyRecordIndex != kNoRecord) DmReleaseRecord(gKeyDB, gKeyRecordIndex, gKeyDirty); gKeyRecordIndex = recordIdx; KeyEdit_FillData(); } else { gRecordKey = MemPtrNew(sizeof(CryptoKey)); if (!gRecordKey) { ErrAlert(memErrNotEnoughSpace); return; } /* Unlock or return immediately. */ if (!Unlock_GetKey(false, gRecordKey)) { /* We don't enter the edit form */ MemPtrFree(gRecordKey); return; } gKeyRecordIndex = recordIdx; FrmGotoForm(KeyEditForm); }}static GUI_SECTION void KeyEdit_GetFields(void){ f_KeyEditForm = FrmGetActiveForm(); f_AllFields[k_KeyName] = UI_GetObjectByID(f_KeyEditForm, KeyNameField); f_AllFields[k_Acct] = UI_GetObjectByID(f_KeyEditForm, AccountField); f_AllFields[k_Passwd] = UI_GetObjectByID(f_KeyEditForm, PasswordField); f_AllFields[k_Notes] = UI_GetObjectByID(f_KeyEditForm, NotesField); f_DateTrg = UI_GetObjectByID(f_KeyEditForm, DateTrigger); f_NotesScrollBar = UI_GetObjectByID(f_KeyEditForm, NotesScrollbar);}/* * Set run-time-only attributes on fields. This is called each time the * form is opened. */static GUI_SECTION void KeyEdit_PrepareFields(void){ FieldAttrType attr; UInt32 encoding; FldGetAttributes(f_AllFields[k_Notes], &attr); attr.hasScrollBar = true; FldSetAttributes(f_AllFields[k_Notes], &attr); /* If the database is read-only, apply that attribute to the * fields. */ if (g_ReadOnly) { Int16 i; for (i = 0; i < k_NumFields; i++) { FldGetAttributes(f_AllFields[i], &attr); attr.editable = false; FldSetAttributes(f_AllFields[i], &attr); } } if (FtrGet(sysFtrCreator, sysFtrNumEncoding, &encoding)) /* if feature not found it is palm latin */ encoding = charEncodingPalmLatin; /* If encoding is latin use our special password font. */ if (gPrefs.useCustomFonts && encoding == charEncodingPalmLatin) { FldSetFont(f_AllFields[k_Acct], fntPassword); FldSetFont(f_AllFields[k_Passwd], fntPassword); }}static GUI_SECTION void KeyEdit_FormOpen(void){#ifdef NOTIFY_SLEEP_HANDLER UInt32 version;#endif gEditFormActive = true; #ifdef NOTIFY_SLEEP_HANDLER /* NotifyRegister is not present in 3.0. We need to check for * (sysFtrCreator, sysFtrNumNotifyMgrVersion) to see if we can * call this. * * This code is currently disabled. We listen for vchrAutoOff * and vchrPowerOff in the main event loop instead. */ if (FtrGet(sysFtrCreator, sysFtrNumNotifyMgrVersion, &version) == 0 && version) SysNotifyRegister(gKeyDBCardNo, gKeyDBID, sysNotifySleepRequestEvent, KeyEdit_Sleep, sysNotifyNormalPriority, NULL);#endif f_needsSort = false; KeyEdit_GetFields(); KeyEdit_PrepareFields(); KeyEdit_FillData(); FrmSetFocus(f_KeyEditForm, FrmGetObjectIndex(f_KeyEditForm, KeyNameField));}static GUI_SECTION void KeyEdit_FormClose(void){#ifdef NOTIFY_SLEEP_HANDLER UInt32 version;#endif UInt32 uniqueId = 0; KeyEdit_Commit(); if (gRecordKey) { CryptoDeleteKey(gRecordKey); MemPtrFree(gRecordKey); gRecordKey = NULL; } Record_Free(gRecord); KeyEdit_FreeFields(); if (gKeyRecordIndex != kNoRecord) { DmReleaseRecord(gKeyDB, gKeyRecordIndex, gKeyDirty); /* Save the uniqueId, so we find the record again after * sorting. */ DmRecordInfo(gKeyDB, gKeyRecordIndex, NULL, &uniqueId, NULL); gKeyRecordIndex = kNoRecord; } if (f_needsSort) Keys_Sort(); /* This is not necessarily a reasonable index, but the list form * will check it before use. */ if (!uniqueId) f_FirstIdx = 0; else { UInt16 index; DmFindRecordByID(gKeyDB, uniqueId, &index); f_FirstIdx = DmPositionInCategory(gKeyDB, index, gPrefs.category); }#ifdef NOTIFY_SLEEP_HANDLER if (FtrGet(sysFtrCreator, sysFtrNumNotifyMgrVersion, &version) == 0 && version) { SysNotifyUnregister(gKeyDBCardNo, gKeyDBID, sysNotifySleepRequestEvent, sysNotifyNormalPriority); }#endif gEditFormActive = false;}/* * Delete the current record. */static GUI_SECTION void KeyEdit_DeleteKey(Boolean saveBackup){ /* Is there a record to remove ? */ if (gKeyRecordIndex == kNoRecord) return; /* If we want to save a backup copy, commit the changes */ if (saveBackup) KeyEdit_Commit(); DmReleaseRecord(gKeyDB, gKeyRecordIndex, gKeyDirty); /* I don't think there's any need to sort here, because nothing else * has moved. */ if (saveBackup) { DmArchiveRecord(gKeyDB, gKeyRecordIndex); } else { DmDeleteRecord(gKeyDB, gKeyRecordIndex); } // Move to the end to make the ordering of the remaining // records simple. DmMoveRecord(gKeyDB, gKeyRecordIndex, DmNumRecords(gKeyDB)); gKeyRecordIndex = kNoRecord;}/* * Delete the record if the user is sure that's what they want. * Return true if deleted and we should return to the list form, * otherwise false. * * TODO: Check if the record is empty; if it is delete without seeking * confirmation. */static GUI_SECTION void KeyEdit_MaybeDelete(void){ UInt16 buttonHit; FormPtr alert; Boolean saveBackup = false; if (App_CheckReadOnly()) return; if (!KeyEdit_IsEmpty()) { alert = FrmInitForm(ConfirmDeleteForm); buttonHit = FrmDoDialog(alert); saveBackup = CtlGetValue(UI_GetObjectByID(alert, SaveArchiveCheck)); FrmDeleteForm(alert); if (buttonHit == CancelBtn) return; } KeyEdit_DeleteKey(saveBackup); FrmGotoForm(ListForm);}static GUI_SECTION void KeyEdit_Generate(void){ FormPtr frm; MemHandle h, oldH; if (App_CheckReadOnly()) return; h = Generate_Run(); if (!h) return; frm = f_KeyEditForm; oldH = FldGetTextHandle(f_AllFields[k_Passwd]); FldSetTextHandle(f_AllFields[k_Passwd], (MemHandle) h); if (oldH) { MemWipe(MemHandleLock(oldH), MemHandleSize(oldH)); MemHandleUnlock(oldH); MemHandleFree(oldH); } FldSetDirty(f_AllFields[k_Passwd], true); FldDrawField(f_AllFields[k_Passwd]); DateSecondsToDate(TimGetSeconds(), &f_lastChanged); f_dirty = true; KeyEdit_SetDateTrigger();}/* * Export if possible. */static GUI_SECTION void KeyEdit_MaybeExport(void){ if (KeyEdit_IsEmpty()) { FrmAlert(ExportEmptyAlert); return; } /* Save the record. As a side effect, write into gRecord. */ KeyEdit_Commit(); ExportKey(gRecord);}static GUI_SECTION Boolean KeyEdit_HandleMenuEvent(EventPtr event){ switch (event->data.menu.itemID) { case HelpCmd: FrmHelp(KeyEditHelp); return true; case DeleteKeyCmd: KeyEdit_MaybeDelete(); return true; case GenerateCmd: KeyEdit_Generate(); return true; case ExportMemoCmd: KeyEdit_MaybeExport(); return true; case UndoAllCmd: if (!App_CheckReadOnly()) { /* * Throw away all the changes to the current key. If this is * an existing key, reload it from the database. If this is a * new key, go back to a blank form. */ if (gKeyRecordIndex != kNoRecord) DmReleaseRecord(gKeyDB, gKeyRecordIndex, gKeyDirty); Record_Free(gRecord); KeyEdit_FreeFields(); KeyEdit_FillData(); } return true; default: return false; }}static GUI_SECTION void KeyEdit_UpdateScrollbar(void){ UInt16 textHeight, fieldHeight, maxValue, scrollPos; FldGetScrollValues(f_AllFields[k_Notes], &scrollPos, &textHeight, &fieldHeight); if (textHeight > fieldHeight) maxValue = textHeight - fieldHeight; else if (scrollPos) maxValue = scrollPos; else maxValue = 0; SclSetScrollBar(f_NotesScrollBar, scrollPos, 0, maxValue, fieldHeight-1);}static GUI_SECTION void KeyEdit_Dragged(EventPtr event){ Int32 lines = event->data.sclExit.newValue - event->data.sclExit.value; WinDirectionType direction; if (lines < 0) { lines = -lines; direction = winUp; } else { direction = winDown; } FldScrollField(f_AllFields[k_Notes], lines, direction);}/* * If possible, scroll the notes field. Otherwise, flip forward or * backward by one record. Before flipping records, commit changes * and act appropriately if the record was actually discarded. */static GUI_SECTION void KeyEdit_PageButton(WinDirectionType dir){ if (FldScrollable(f_AllFields[k_Notes], dir)) { Int16 lines; lines = FldGetVisibleLines(f_AllFields[k_Notes]); FldScrollField(f_AllFields[k_Notes], lines, dir); KeyEdit_UpdateScrollbar(); } else { UInt16 recIndex = gKeyRecordIndex; Int16 direction; direction = (dir == winDown) ? dmSeekForward : dmSeekBackward; if (DmSeekRecordInCategory(gKeyDB, &recIndex, 1, direction, gPrefs.category) == errNone) KeyEdit_GotoRecord(recIndex); }}static const UInt16 idLinks[] = { 0, KeyNameField, AccountField, PasswordField, NotesField, -1};static GUI_SECTION Boolean KeyEdit_Arrow(int dir){ FormPtr frm; UInt16 activeIdx; UInt16 activeId, nextId; UInt16 i; frm = f_KeyEditForm; activeIdx = FrmGetFocus(frm); activeId = FrmGetObjectId(frm, activeIdx); if (!activeId) return false; /* Otherwise, look for this field and work out where to go next. */ for (i = 0; ; i++) { if (idLinks[i] == (UInt16) -1) return false; if (idLinks[i] == activeId) { nextId = idLinks[i + dir]; if (nextId == 0 || nextId == (UInt16) -1) return false; FrmSetFocus(frm, FrmGetObjectIndex(frm, nextId)); return true; } } return true;}static GUI_SECTION Boolean KeyEdit_HandleKeyDownEvent(EventPtr event){ const int chr = event->data.keyDown.chr; if (TxtCharIsHardKey(event->data.keyDown.modifiers, chr)) { FrmGotoForm(ListForm); return true; } switch (chr) { case pageUpChr: case pageDownChr: KeyEdit_PageButton(chr == pageDownChr ? winDown : winUp); return true; case nextFieldChr: case prevFieldChr: return KeyEdit_Arrow(chr == nextFieldChr ? +1 : -1); default: return false; }}static GUI_SECTION void KeyEdit_ChooseDate(void) { Boolean ok; MemHandle handle; Char *title; Int16 year, month, day; year = f_lastChanged.year + 1904; month = f_lastChanged.month; day = f_lastChanged.day; /* Limit to protect against SelectDay aborting. */ if (month < 1 || month > 12 || day < 1 || day > 31) { month = day = 1; } title = MemHandleLock(handle = DmGetResource (strRsc, ChangeDateStr)); ok = SelectDay(selectDayByDay, &month, &day, &year, title); MemHandleUnlock(handle); DmReleaseResource(handle); if (ok) { f_lastChanged.year = year - 1904; f_lastChanged.month = month; f_lastChanged.day = day; f_dirty = true; KeyEdit_SetDateTrigger(); }}static GUI_SECTION void KeyEdit_CategorySelected(void){ Boolean categoryChanged; if (App_CheckReadOnly()) return; categoryChanged = Category_Selected(&gRecord->category, false); if (categoryChanged) { f_dirty = true; KeyEdit_UpdateCategory(); if (gPrefs.category != dmAllCategories) { gPrefs.category = gRecord->category; KeyEdit_UpdateTitle(); } }}GUI_SECTION Boolean KeyEdit_HandleEvent(EventPtr event){ switch (event->eType) { case ctlSelectEvent: switch (event->data.ctlSelect.controlID) { case LockBtn: Snib_Eradicate (); FrmGotoForm(ListForm); return true; case DoneBtn: FrmGotoForm(ListForm); return true; case GenerateBtn: KeyEdit_Generate(); return true; case DateTrigger: KeyEdit_ChooseDate(); return true; case CategoryTrigger: KeyEdit_CategorySelected(); return true; default: return false; } case fldChangedEvent: if (event->data.fldChanged.fieldID == NotesField) { KeyEdit_UpdateScrollbar(); return true; } break; case frmOpenEvent: KeyEdit_FormOpen(); return true; case frmSaveEvent: KeyEdit_Commit(); return true; case frmCloseEvent: KeyEdit_FormClose(); return false; case keyDownEvent: return KeyEdit_HandleKeyDownEvent(event); case menuEvent: if (Common_HandleMenuEvent(event) || KeyEdit_HandleMenuEvent(event)) return true; break; case sclRepeatEvent: case sclExitEvent: KeyEdit_Dragged(event); break; default: } return false;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -