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

📄 todotransfer.c

📁 我的Palm OS 5 SDK zhCN_PIMApps代码。 使用codewarrior 开发环境
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************
 *
 * Copyright (c) 1995-2003 PalmSource, Inc. All rights reserved.
 *
 * File: ToDoTransfer.c
 *
 * Release: Palm OS 5 SDK (68K) R3.
 *
 * Description:
 *      To Do routines to transfer records.
 *
 *****************************************************************************/

#include <PalmOS.h>

#include <PdiLib.h>
#include <UDAMgr.h>
#include <TraceMgr.h>

#include <PalmUtils.h>

#include "ToDo.h"
#include "ToDoRsc.h"

#define identifierLengthMax		40
#define tempStringLengthMax		20
#define defaultPriority				1
#define incompleteFlag				0x7F
#define todoSuffix					".vcs"
#define todoMIMEType				"text/x-vCalendar"

// Aba: internal version of vCalendar. Must be updated
// the export side of the vCalendar code evoluate

#define kVObjectVersion				"5.3"

extern Char * GetToDoNotePtr (ToDoDBRecordPtr recordP);	// needed to see if ToDo empty

/***********************************************************************
 *
 * FUNCTION:		PrvPdiLibLoad
 *
 * DESCRIPTION:		Load Pdi library
 * PARAMETERS:		a pointer to an integer: the refNum of the libary
 *						return whether the library had to be loaded (and therefore
 *								needs to be unloaded)
 *
 * RETURNED:		An error if library is not found
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			ABa		4/10/00		Created
 *
 ***********************************************************************/
static Err PrvPdiLibLoad(UInt16* refNum, Boolean *loadedP)
{
    Err	error;

    // Load the Pdi library

    // Check if the library was pre-loaded (this is useful if we can
    // be called from another app via an action code and want to use an existing
    // instance of the library in case our caller has already loaded it)
    *loadedP = false;
    error = SysLibFind(kPdiLibName, refNum);
    if (error != 0)
    {
        error = SysLibLoad(sysResTLibrary, sysFileCPdiLib, refNum);
		TraceOutput(TL(appErrorClass, "Loading Pdi library."));
        if (! error)
            *loadedP = true;
    }
    if (error)
    {
        // We're here because the Pdi library failed to load.
        // Inform the user or do something else defensive here.
        ErrNonFatalDisplay(kPdiLibName " not found");
        return error;
    }
    error = PdiLibOpen(*refNum);

    return error;
}

/***********************************************************************
 *
 * FUNCTION:		PrvPdiLibUnload
 *
 * DESCRIPTION:		Unload Pdi library
 * PARAMETERS:		The refnum of the pdi library 
 *						Whether the library was loaded (and therefore needs to be unloaded)
 *
 * RETURNED:		NONE
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			ABa		4/10/00		Created
 *
 ***********************************************************************/
static void PrvPdiLibUnload(UInt16 refNum, Boolean loaded)
{
	if (PdiLibClose(refNum) == 0)
	{
		TraceOutput(TL(appErrorClass, "Unloading Pdi library."));
		if (loaded)
			SysLibRemove(refNum);
	}
}

/***********************************************************************
 *
 * FUNCTION:		PrvTransferCleanFileName
 *
 * DESCRIPTION:		Remove dot characters in file name but not the least
 * PARAMETERS:		a pointer to a string
 *
 * RETURNED:		String parameter doesn't contains superfluous dot characters
 *
 * REVISION HISTORY:
 *			Name	Date		Description
 *			----	----		-----------
 *			ABa		7/28/00		Created
 *
 ***********************************************************************/
static void PrvTransferCleanFileName(Char* ioFileName)
{
	Char* 	mayBeLastDotP;
	Char*  	lastDotP;
	UInt32	chrFullStopSize = TxtCharSize(chrFullStop);	
    
	// prevent NULL & empty string
	if (ioFileName == NULL || *ioFileName == 0)
		return;

	// remove dot but not the last one
	mayBeLastDotP = StrChr(ioFileName, 	chrFullStop);
	while ((lastDotP = StrChr(mayBeLastDotP + chrFullStopSize, chrFullStop)))
	{
		// remove the dot
		StrCopy(mayBeLastDotP, mayBeLastDotP + chrFullStopSize);
		mayBeLastDotP = lastDotP - chrFullStopSize;
	}
}

/************************************************************
 *
 * FUNCTION: MatchDateToken
 *
 * DESCRIPTION: Extract date from the given string
 *
 * PARAMETERS:
 *		tokenP	-	string ptr from which to extract
 *		dateP		-	ptr where to store date (optional)
 *
 * RETURNS: nothing
 *
 * REVISION HISTORY:
 *			Name		Date		Description
 *			----		----		-----------
 *			djk		2/2/98	Copied code from Date Book
 *
 *************************************************************/
static void MatchDateToken (const char* tokenP,	DateType * dateP)
{
    char			identifier[identifierLengthMax];
    int			nv;

    // Use identifier[] as a temp buffer to copy parts of the vCal DateTime
    // so we can convert them to correct form.  This date portion
    // is 4 chars (date) + 2 chars (month) + 2 chars (day) = 8 chars long

    // Read the Year
    StrNCopy(identifier, tokenP, 4);
    identifier[4] = nullChr;
    nv = StrAToI(identifier);
    // Validate the number and use it.
    if (nv < firstYear || lastYear < nv)
        nv = firstYear;
    dateP->year = nv - firstYear;
    tokenP += StrLen(identifier) * sizeof(Char);

    // Read the Month
    StrNCopy(identifier, tokenP, 2);
    identifier[2] = nullChr;
    nv = StrAToI(identifier);
    // Validate the number and use it.
    if (nv < 1 || monthsInYear < nv)
        nv = 1;
    dateP->month = nv;
    tokenP += StrLen(identifier) * sizeof(Char);

    // Read the Day
    StrNCopy(identifier, tokenP, 2);
    identifier[2] = nullChr;
    nv = StrAToI(identifier);
    // Validate the number and use it.
    if (nv < 1 || 31 < nv)
        nv = 1;
    dateP->day = nv;
    tokenP += StrLen(identifier) * sizeof(Char);
}


/***********************************************************************
 *
 * FUNCTION:    SetDescriptionAndFilename
 *
 * DESCRIPTION: Derive and allocate a decription and filename from some text.
 *
 * PARAMETERS:  textP - the text string to derive the names from
 *					 descriptionPP - pointer to set to the allocated description
 *					 descriptionHP - MemHandle to set to the allocated description
 *					 filenamePP - pointer to set to the allocated filename
 *					 filenameHP - MemHandle to set to the allocated description
 *					 prefix - the scheme with ":" suffix and optional "?" prefix
 *
 * RETURNED:    a description and filename are allocated and the pointers are set
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         roger   11/4/97   Initial Revision
 *
 ***********************************************************************/
static void SetDescriptionAndFilename(Char * textP, Char **descriptionPP,
                                      MemHandle *descriptionHP, Char **filenamePP, MemHandle *filenameHP,
                                      const Char * const prefix)
{
    Char * descriptionP;
    Int16 descriptionSize;
    Int16 descriptionWidth;
    Boolean descriptionFit;
    Char * spaceP;
    Char * filenameP;
	MemHandle resourceH;
	Char * resourceP;
    UInt8 filenameLength;
	UInt8 schemeLength;
    Coord unused;


    descriptionSize = StrLen(textP);
    WinGetDisplayExtent(&descriptionWidth, &unused);
    FntCharsInWidth (textP, &descriptionWidth, &descriptionSize, &descriptionFit);

    if (descriptionSize > 0)
    {
        *descriptionHP = MemHandleNew(descriptionSize+sizeOf7BitChar('\0'));
        if (*descriptionHP)
        {
            descriptionP = MemHandleLock(*descriptionHP);
            MemMove(descriptionP, textP, descriptionSize);
            descriptionP[descriptionSize] = nullChr;
        }
    }
    else
    {
        *descriptionHP = DmGetResource(strRsc, BeamDescriptionStr);
        descriptionP = MemHandleLock(*descriptionHP);
        DmReleaseResource(*descriptionHP);
        *descriptionHP = NULL;			// so the resource isn't freed
    }


    if (descriptionSize > 0)
    {
        // Now form a file name.  Use only the first word or two.
        spaceP = StrChr(descriptionP, spaceChr);
        if (spaceP)
            // Check for a second space
            spaceP = StrChr(spaceP + sizeOf7BitChar(spaceChr), spaceChr);

        // If at least two spaces were found then use only that much of the description.
        // If less than two spaces were found then use all of the description.
        if (spaceP)
            filenameLength = spaceP - descriptionP;
        else
            filenameLength = StrLen(descriptionP);


        // Allocate space and form the filename
		schemeLength = StrLen(prefix);
        *filenameHP = MemHandleNew(schemeLength + filenameLength + StrLen(todoSuffix) + sizeOf7BitChar('\0'));
        filenameP = MemHandleLock(*filenameHP);
        if (filenameP)
        {
			StrCopy(filenameP, prefix);
            MemMove(&filenameP[schemeLength], descriptionP, filenameLength);
            MemMove(&filenameP[schemeLength + filenameLength], todoSuffix,
                    StrLen(todoSuffix) + sizeOf7BitChar('\0'));
        }
    }
    else
    {
		resourceH = DmGetResource(strRsc, BeamFilenameStr);
		resourceP = MemHandleLock(resourceH);
		
		// Allocate space and form the filename
		filenameLength = StrLen(resourceP);
		schemeLength = StrLen(prefix);
		*filenameHP = MemHandleNew(schemeLength + filenameLength + sizeOf7BitChar('\0'));
		filenameP = MemHandleLock(*filenameHP);
		if (filenameP)
			{
			StrCopy(filenameP, prefix);
			StrCat(filenameP, resourceP);
			}
		
		MemHandleUnlock(resourceH);
		DmReleaseResource(resourceH);
    }


    *descriptionPP = descriptionP;
    *filenamePP = filenameP;
}


/***********************************************************************
 *
 * FUNCTION:    ToDoSendRecordTryCatch
 *
 * DESCRIPTION: Send a record.
 *
 * PARAMETERS:	 dbP - pointer to the database to add the record to
 * 				 recordNum - the record number to send
 * 				 recordP - pointer to the record to send
 * 				 exgSocketP - the exchange socket used to send
 *
 * RETURNED:    0 if there's no error
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         roger  12/11/97  Initial Revision
 *
 ***********************************************************************/
static Err ToDoSendRecordTryCatch (DmOpenRef dbP, Int16 recordNum,
      ToDoDBRecordPtr recordP, UDAWriterType* media)
{
    volatile Err error = 0;


    UInt16 pdiRefNum;

    PdiWriterType* writer;
    Boolean loaded;

    if ((error = PrvPdiLibLoad(&pdiRefNum, &loaded)))
        return error;

    writer = PdiWriterNew(pdiRefNum, media, kPdiPalmCompatibility);
    if (writer)
    {

        // An error can happen anywhere during the send process.  It's easier just to
        // catch the error.  If an error happens, we must pass it into ExgDisconnect.
        // It will then cancel the send and display appropriate ui.
        ErrTry
        {
		    PdiWriteBeginObject(pdiRefNum, writer, kPdiPRN_BEGIN_VCALENDAR);
		    PdiWriteProperty(pdiRefNum, writer, kPdiPRN_VERSION);
		    PdiWritePropertyValue(pdiRefNum, writer, (Char*)"1.0", kPdiWriteData);

			PdiWritePropertyStr(pdiRefNum, writer, "X-PALM", kPdiNoFields, 1);
			PdiWritePropertyValue(pdiRefNum, writer, (Char*) kVObjectVersion, kPdiWriteData);

            ToDoExportVCal(dbP, recordNum, recordP, pdiRefNum, writer, true);
		    PdiWriteEndObject(pdiRefNum, writer, kPdiPRN_END_VCALENDAR);
			error = UDAWriterFlush(media);
        }

        ErrCatch(inErr)
        {
            error = inErr;
        } ErrEndCatch

        PdiWriterDelete(pdiRefNum, &writer);
    }
    else
    {
    	error = exgMemError;
    }
	PrvPdiLibUnload(pdiRefNum, loaded);
    return error;
}


/***********************************************************************
 *
 * FUNCTION:    ToDoSendRecord
 *
 * DESCRIPTION: Send a record.
 *
 * PARAMETERS:	 dbP - pointer to the database
 * 				 recordNum - the record to send
 *				 prefix - the scheme with ":" suffix and optional "?" prefix
 *				 noDataAlertID - alert to put up if there is nothing to send
 *
 * RETURNED:    true if the record is found and sent
 *
 * REVISION HISTORY:
 *         Name   Date      Description
 *         ----   ----      -----------
 *         roger  5/9/97    Initial Revision
 *
 ***********************************************************************/
extern void ToDoSendRecord (DmOpenRef dbP, Int16 recordNum, const Char * const prefix, UInt16 noDataAlertID)
{
    ToDoDBRecordPtr recordP;
    MemHandle recordH;
    MemHandle descriptionH = NULL;
    Err error;
    ExgSocketType exgSocket;
    MemHandle nameH = NULL;
    Boolean empty;
    UDAWriterType* media;
    
    // important to init structure to zeros...
    MemSet(&exgSocket, sizeof(exgSocket), 0);

    // Form a description of what's being sent.  This will be displayed
    // by the system send dialog on the sending and receiving devices.
    recordH = (MemHandle) DmGetRecord(dbP, recordNum);
    recordP = (ToDoDBRecordPtr) MemHandleLock(recordH);

    // If the description field is empty and the note field is empty,
    // consider the record empty.
    empty = (! recordP->description) && (! *GetToDoNotePtr(recordP));

    if (!empty)
    {
        // Set the exg description to the record's description.
        SetDescriptionAndFilename(&recordP->description, &exgSocket.description,
                                  &descriptionH, &exgSocket.name, &nameH, prefix);

		//ABa: remove superfluous '.' characters
		PrvTransferCleanFileName(exgSocket.name);
		TraceOutput(TL(appErrorClass, "ToDoSendRecord: description = %s, name = %s", exgSocket.description, exgSocket.name));

        exgSocket.length = MemHandleSize(recordH) + 100;		// rough guess
        // Note, a hack in exgmgr will remap this to datebook
        
        // NOTE: ABa To test that the DateBook sublaunches the ToDo app
        // when parsing VTODO, just comment out the next line
        // And do the same in ToDoSendCategory
        exgSocket.target = sysFileCToDo;	// include target since todo and date book share an extension
        exgSocket.type = (Char *)todoMIMEType;
        
        error = ExgPut(&exgSocket);   // put data to destination
		// ABa: Changes to use new streaming mechanism 
        media = UDAExchangeWriterNew(&exgSocket,  512);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -