⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sugarmemoedit.c

📁 Palm上著名的背单词软件的源码
💻 C
📖 第 1 页 / 共 3 页
字号:


			// 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, &currentRecord, &currentRecordH);

	hasData = WordRecordContainsData(&currentRecord);

	// 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 + -