📄 sugarmemoedit.c
字号:
// Update the text field to use whatever text we have.
FldSetTextHandle (fld, textH);
MemHandleUnlock(recordH);
FrmAlert(DeviceFullAlert);
// The field may no longer be the same height. This row and those
// below may need to be recalced. Mark this row and those
// below it not usable and reload the table.
numOfRows = TblGetNumberOfRows(table);
while (row < numOfRows)
{
TblSetRowUsable(table, row, false);
row++;
}
EditFormLoadTable(FrmGetActiveForm());
redraw = true; // redraw the table showing change lost
}
}
// Free the memory used for the field's text because the table suppresses it.
FldFreeMemory (fld);
return redraw;
}
static void EditFormLoadTable( FormType* frmP )
{
UInt16 row;
UInt16 numRows;
UInt16 lineHeight;
UInt16 fieldIndex;
UInt16 lastFieldIndex;
UInt16 dataHeight;
UInt16 tableHeight;
UInt16 columnWidth;
UInt16 pos, oldPos;
UInt16 height, oldHeight;
TablePtr table;
Boolean rowUsable;
Boolean rowsInserted = false;
Boolean lastItemClipped;
RectangleType r;
WordRecordType record;
MemHandle recordH;
// Get the current record
GetWordRecord (CurrentDB, CurrentRecord, &record, &recordH);
// Get the height of the table and the width of edit column.
table = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EditEditTable));
TblGetBounds (table, &r);
tableHeight = r.extent.y;
columnWidth = TblGetColumnWidth (table, dataColumn);
// If we currently have a selected record, make sure that it is not
// above the first visible record.
if (CurrentFieldIndex != noFieldIndex)
{
if (CurrentFieldIndex < TopVisibleFieldIndex)
TopVisibleFieldIndex = CurrentFieldIndex;
}
row = 0;
dataHeight = 0;
oldPos = pos = 0;
fieldIndex = TopVisibleFieldIndex;
lastFieldIndex = fieldIndex;
// Load records into the table.
while (fieldIndex <= MaxFieldIndex)
{
// Compute the height of the field's text string.
height = EditGetFieldHeight (table, fieldIndex, columnWidth, tableHeight, &record);
// Is there enought room for at least one line of the the decription.
lineHeight = FntLineHeight ();
if (tableHeight >= dataHeight + lineHeight)
{
rowUsable = TblRowUsable (table, row);
// Get the height of the current row.
if (rowUsable)
oldHeight = TblGetRowHeight (table, row);
else
oldHeight = 0;
// If the field is not already being displayed in the current
// row, load the field into the table.
if ((! rowUsable) || (TblGetRowID (table, row) != fieldIndex))
EditInitTableRow(frmP, table, row, fieldIndex, height, &record);
// If the height or the position of the item has changed draw the item.
else if (height != oldHeight)
{
TblSetRowHeight (table, row, height);
TblMarkRowInvalid (table, row);
}
else if (pos != oldPos)
{
TblMarkRowInvalid (table, row);
}
pos += height;
oldPos += oldHeight;
lastFieldIndex = fieldIndex;
fieldIndex++;
row++;
}
dataHeight += height;
// Is the table full?
if (dataHeight >= tableHeight)
{
// If we have a currently selected field, make sure that it is
// not below the last visible field. If the currently selected
// field is the last visible record, make sure the whole field
// is visible.
if (CurrentFieldIndex == noFieldIndex)
break;
// Above last visible?
else if (CurrentFieldIndex < fieldIndex)
break;
// Last visible?
else if (fieldIndex == lastFieldIndex)
{
if ((fieldIndex == TopVisibleFieldIndex) || (dataHeight == tableHeight))
break;
}
// Remove the top item from the table and reload the table again.
TopVisibleFieldIndex++;
fieldIndex = TopVisibleFieldIndex;
// Below last visible.
// else
// TopVisibleFieldIndex = CurrentFieldIndex;
row = 0;
dataHeight = 0;
oldPos = pos = 0;
}
}
// Hide the item that don't have any data.
numRows = TblGetNumberOfRows (table);
while (row < numRows)
{
TblSetRowUsable (table, row, false);
row++;
}
// If the table is not full and the first visible field is
// not the first field in the record, displays enough fields
// to fill out the table by adding fields to the top of the table.
while (dataHeight < tableHeight)
{
fieldIndex = TopVisibleFieldIndex;
if (fieldIndex == 0) break;
fieldIndex--;
// Compute the height of the field.
height = EditGetFieldHeight (table, fieldIndex, columnWidth, tableHeight, &record);
// If adding the item to the table will overflow the height of
// the table, don't add the item.
if (dataHeight + height > tableHeight)
break;
// Insert a row before the first row.
TblInsertRow (table, 0);
EditInitTableRow(frmP, table, 0, fieldIndex, height, &record);
TopVisibleFieldIndex = fieldIndex;
rowsInserted = true;
dataHeight += height;
}
// If rows were inserted to full out the page, invalidate the whole
// table, it all needs to be redrawn.
if (rowsInserted)
TblMarkTableInvalid (table);
// If the height of the data in the table is greater than the height
// of the table, then the bottom of the last row is clip and the
// table is scrollable.
lastItemClipped = (dataHeight > tableHeight);
// Update the scroll arrows.
EditUpdateScrollers(frmP, lastFieldIndex, lastItemClipped);
MemHandleUnlock(recordH);
TblDrawTable(table);
}
//Get the field height
UInt16 EditGetFieldHeight (TablePtr table, UInt16 fieldIndex, Int16 columnWidth, Int16 maxHeight,
WordRecordType* record)
{
Int16 row;
Int16 column;
UInt16 index;
Int16 height = 0;
UInt16 lineHeight;
Char * str;
FieldPtr fld;
FontID currFont;
if (FieldMap[fieldIndex] == WordFieldPhonetic) {
currFont = FntSetFont(PhoneticSmallFont);
height = 0;
height += FntLineHeight();
FntSetFont(currFont);
return (height);
}
if (TblEditing (table))
{
TblGetSelection (table, &row, &column);
if (fieldIndex == TblGetRowID (table, row))
{
fld = TblGetCurrentField (table);
str = FldGetTextPtr (fld);
}
else
{
index = FieldMap[fieldIndex];
str = record->field[index];
}
}
else
{
index = FieldMap[fieldIndex];
str = record->field[index];
}
FntSetFont(stdFont);
height = FldCalcFieldHeight (str, columnWidth);
lineHeight = FntLineHeight ();
height = min (height, (maxHeight / lineHeight));
height *= lineHeight;
return (height);
}
void EditInitTableRow( FormType* frmP, TablePtr table, UInt16 row, UInt16 fieldIndex,
Int16 rowHeight, WordRecordType* record)
{
// Make the row usable.
TblSetRowUsable (table, row, true);
// Set the height of the row to the height of the desc
TblSetRowHeight (table, row, rowHeight);
// Store the record number as the row id.
TblSetRowID (table, row, fieldIndex);
// Mark the row invalid so that it will draw when we call the
// draw routine.
TblMarkRowInvalid (table, row);
TblSetItemPtr(table, row, labelColumn, fieldLabel[FieldMap[fieldIndex]]);
if (FieldMap[fieldIndex] == WordFieldPhonetic){
TblSetItemStyle (table, row, dataColumn, customTableItem);
}
else{
TblSetItemStyle (table, row, dataColumn, textTableItem);
}
}
void EditFormNextWord(Boolean next){
UInt16 qIndex, num;
HeaderItem item;
Int16 direction;
switch (tabCurrentSelected){
case StudyListTab:
if (!FindHeaderItemByDBIndex(CurrentDB, LearningRecordIndex, CurrentRecord, &qIndex))
return;
num = GetHeaderItemNumber(CurrentDB, LearningRecordIndex);
if (next){
if (qIndex == num - 1) return;
qIndex ++;
}
else{
if (qIndex == 0) return;
qIndex --;
}
GetHeaderItem(CurrentDB, LearningRecordIndex, &item, qIndex);
DmFindRecordByID(CurrentDB, item, &CurrentRecord);
break;
case RawTab:
case AllTab:
if (next) {
direction = dmSeekForward;
qIndex = CurrentRecord + 1;
}
else {
direction = dmSeekBackward;
if (CurrentRecord == FirstWordRecord) return;
qIndex = CurrentRecord - 1;
}
if (!SeekNextRecord(&qIndex, direction)) return;
CurrentRecord = qIndex;
break;
default:
break;
}
EditFormLoadControls();
EditFormLoadCategory();
EditFormLoadTable(FrmGetActiveForm());
FrmDrawForm(FrmGetActiveForm());
EditUpdateHorizonScrollers();
}
void EditUpdateScrollers (FormPtr frmP, UInt16 bottomFieldIndex, Boolean lastItemClipped){
TableType * table = GetObjectPtr(EditEditTable);
UInt16 upIndex;
UInt16 downIndex;
Boolean scrollableUp = false;
Boolean scrollableDown = false;
// Boolean
// If the first field displayed is not the fist field in the record,
// enable the up scroller.
if (TopVisibleFieldIndex > 0) scrollableUp = true;
if (lastItemClipped || (bottomFieldIndex < MaxFieldIndex)) scrollableDown = true;
// If the last field displayed is not the last field in the record,
// enable the down scroller.
// Update the scroll button.
upIndex = FrmGetObjectIndex (frmP, EditScrollUpRepeating);
downIndex = FrmGetObjectIndex (frmP, EditScrollDownRepeating);
FrmUpdateScrollers (frmP, upIndex, downIndex, scrollableUp, scrollableDown);
}
void EditUpdateHorizonScrollers(){
UInt16 qIndex, num;
FormType* frmP = FrmGetActiveForm();
Boolean scrollableUp = true;
Boolean scrollableDown = true;
switch(tabCurrentSelected){
case StudyListTab:
FindHeaderItemByDBIndex(CurrentDB, LearningRecordIndex, CurrentRecord, &qIndex);
num = GetHeaderItemNumber(CurrentDB, LearningRecordIndex);
if (qIndex == 0) scrollableUp = false;
if (qIndex == num - 1) scrollableDown = false;
break;
case RawTab:
case AllTab:
if (CurrentRecord == FirstWordRecord) scrollableUp = false;
else {
qIndex = CurrentRecord - 1;
if (!SeekNextRecord(&qIndex, dmSeekBackward)) scrollableUp = false;
}
qIndex = CurrentRecord + 1;
if (!SeekNextRecord(&qIndex, dmSeekForward)) scrollableDown = false;
break;
}
if (scrollableUp) ShowObject(EditPrevRepeating);
else HideObject(EditPrevRepeating);
if (scrollableDown) ShowObject(EditNextRepeating);
else HideObject(EditNextRepeating);
}
UInt16 EditFormSaveRecord ()
{
MemHandle currentRecordH;
WordRecordType currentRecord;
FormPtr frmP;
TablePtr tableP;
Boolean hasData;
// Make sure the field being edited is saved
frmP = FrmGetFormPtr(EditForm);
tableP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EditEditTable));
TblReleaseFocus(tableP);
// The record may have already been delete by the Delete menu command
// or the details dialog. If there isn't a CurrentRecord assume the
// record has been deleted.
if (CurrentRecord == noRecord)
{
return BrowseForm;
}
// If there is no data then then delete the record.
// If there is data but no name data then demand some.
GetWordRecord(CurrentDB, CurrentRecord, ¤tRecord, ¤tRecordH);
hasData = WordRecordContainsData(¤tRecord);
// Unlock before the DeleteRecord. We can only rely on
// NULL pointers from here on out.
MemHandleUnlock(currentRecordH);
// If none are the fields contained anything then
// delete the field.
if (!hasData)
{
WordDBDeleteRecord(false); // uniq ID wasted? Yes. We don't care.
return BrowseForm;
}
// The record's category may have been changed. The CurrentCategory
// isn't supposed to change in this case. Make sure the CurrentRecord
// is still visible in this category or pick another one near it.
//if (!SeekRecord(&CurrentRecord, 0, dmSeekBackward))
//if (!SeekRecord(&CurrentRecord, 0, dmSeekForward))
//CurrentRecord = noRecord;
return BrowseForm;
}
void EditNewRecord ()
{
WordRecordType newRecord;
WordFields i;
UInt16 attr;
Err err;
MemorizingStatus memoStatus ={2.50, //e-factor
40, //difficulty
0, //total lapse
0, //total recall
0, //recent lapse
0, //recent recall
0, //step
0, //last test
0, //current test
0, //next test
0, //first learn
0}; //create
DateType today;
UInt32 seconds;
newRecord.header.allBits = 0;
SetBitMacro(newRecord.header.allBits, RawQueue);
newRecord.ltStatus.learningStatus = 0;
newRecord.memoStatus = memoStatus;
seconds = TimGetSeconds();
DateSecondsToDate(seconds, &today);
newRecord.memoStatus.create = today;
for (i = WordFieldQuestion; i < WordFieldsCount; i++)
newRecord.field[i] = NULL;
err = NewWordRecord(CurrentDB, &newRecord, &CurrentRecord);
if (err)
{
FrmAlert(DeviceFullAlert);
return;
}
// Set it's category to the category being viewed.
// If the category is All then set the category to unfiled.
DmRecordInfo (CurrentDB, CurrentRecord, &attr, NULL, NULL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -