diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e43b0f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.DS_Store diff --git a/README.adoc b/README.adoc index 3c12a53..bf7609e 100644 --- a/README.adoc +++ b/README.adoc @@ -10,4 +10,5 @@ Contributers - https://github.com/acesso[*@acesso*]: SDKs 1.0, 2.0, 3.1, 3.5, and 4.0 - https://github.com/jichu4n[*@jichu4n*]: SDK 5.0r3 - https://github.com/stevelittle[*@stevelittle*]: SDK 5.0r4 +- https://github.com/Tavisco[*@Tavisco*]: Handera SDK 1.05 diff --git a/handera-sdk-105/doc/Companion/Programming_Companion.pdf b/handera-sdk-105/doc/Companion/Programming_Companion.pdf new file mode 100644 index 0000000..a436a50 Binary files /dev/null and b/handera-sdk-105/doc/Companion/Programming_Companion.pdf differ diff --git a/handera-sdk-105/doc/Reference Manual/ReferenceManual.pdf b/handera-sdk-105/doc/Reference Manual/ReferenceManual.pdf new file mode 100644 index 0000000..aa2d527 Binary files /dev/null and b/handera-sdk-105/doc/Reference Manual/ReferenceManual.pdf differ diff --git a/handera-sdk-105/examples/ExampleA/ExampleA.mcp b/handera-sdk-105/examples/ExampleA/ExampleA.mcp new file mode 100644 index 0000000..016dffc Binary files /dev/null and b/handera-sdk-105/examples/ExampleA/ExampleA.mcp differ diff --git a/handera-sdk-105/examples/ExampleA/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleA/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..7b5154f Binary files /dev/null and b/handera-sdk-105/examples/ExampleA/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleA/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleA/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleA/Src/starter.c b/handera-sdk-105/examples/ExampleA/Src/starter.c new file mode 100644 index 0000000..d34d13c --- /dev/null +++ b/handera-sdk-105/examples/ExampleA/Src/starter.c @@ -0,0 +1,478 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project : Example A + * + *****************************************************************************/ + +#include +#include "StarterRsc.h" + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +typedef StarterAppInfoType* StarterAppInfoPtr; + +FontID currentFont = stdFont; +Char helloStr[] = "Hello World"; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_A' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ + + /*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + + /*********************************************************************** + * + * FUNCTION: PrvSetHelloFont + * + * DESCRIPTION: Sets the font and centers the field horizontally + * + * PARAMETERS: + * + * RETURNED: nothing + * + ***********************************************************************/ +static void PrvCenterTextField(FormPtr frmP, FieldPtr fldP, Boolean draw) +{ + RectangleType r, fr; + Int16 stringWidth; + +/*------------------------------------------------------------------------ + * First get the width of the field string in pixels. + *----------------------------------------------------------------------*/ + FntSetFont(FldGetFont(fldP)); + stringWidth = FntCharsWidth(helloStr, StrLen(helloStr)); + +/*------------------------------------------------------------------------ + * Now center the field based on width of string in pixels. + *----------------------------------------------------------------------*/ + FrmGetFormBounds(frmP, &fr); + FrmGetObjectBounds(frmP, FrmGetObjectIndex(frmP, MainHelloField), &r); + + if (draw) + FldEraseField(fldP); + + r.topLeft.x = (fr.extent.x/2) - (stringWidth/2); + FrmSetObjectBounds(frmP, FrmGetObjectIndex(frmP, MainHelloField), &r); + + if (draw) + FldDrawField(fldP); +} + +/*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + ***********************************************************************/ +static void MainFormInit(FormPtr frmP) +{ + FieldPtr fldP; + Char *tmp; + + currentFont = stdFont; + +/*------------------------------------------------------------------------ + * Initialize the field to "Hello World" and set its font + *----------------------------------------------------------------------*/ + fldP = (FieldPtr)GetObjectPtr(MainHelloField); + if ((tmp = FldGetTextPtr(fldP)) != NULL) + MemPtrFree(tmp); + tmp = (Char *)MemPtrNew(StrLen(helloStr) + 1); + StrCopy(tmp, helloStr); + FldSetTextPtr(fldP, tmp); + FldSetFont((FieldPtr)GetObjectPtr(MainHelloField), currentFont); + + PrvCenterTextField(frmP, (FieldPtr)GetObjectPtr(MainHelloField), false);; +} + + + /*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + UInt16 formID; + FormPtr frmP, aboutFrmP; + + frmP = FrmGetActiveForm(); + formID = FrmGetFormId (frmP); + + switch (command) + { + case MainOptionsAboutExampleA: + MenuEraseStatus(0); + aboutFrmP = FrmInitForm (AboutForm); + FrmDoDialog (aboutFrmP); // Display the About Box. + FrmDeleteForm (aboutFrmP); + handled = true; + break; + + case MainOptionsFont : + currentFont = FontSelect(currentFont); + FldSetFont((FieldPtr)GetObjectPtr(MainHelloField), currentFont); + PrvCenterTextField(frmP, (FieldPtr)GetObjectPtr(MainHelloField), true); + handled = true; + break; + } + + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit(frmP); + FrmDrawForm (frmP); + handled = true; + break; + + default: + break; + } + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + +/*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + + /*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: Get the current application's preferences. + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + + return(errNone); +} + +/*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + + /*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + Err error; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + if ((error = AppStart()) != errNone) + return(error); + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + + default: + break; + + } + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} diff --git a/handera-sdk-105/examples/ExampleA/StarterRsc.h b/handera-sdk-105/examples/ExampleA/StarterRsc.h new file mode 100644 index 0000000..f2abdc9 --- /dev/null +++ b/handera-sdk-105/examples/ExampleA/StarterRsc.h @@ -0,0 +1,51 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 4:45:12 PM on Wednesday, April 04, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleA\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleA" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) +#define MainGlobeBitMap 1200 //(Left Origin = 50, Top Origin = 50, Bitmap Resource ID = 1200, Usable = 1) +#define MainHelloField 1002 //(Left Origin = 53, Top Origin = 138, Width = 80, Height = 20, Usable = 1, Editable = 0, Underline = 0, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 80, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 0) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) +#define AboutText1Label 1103 //(Left Origin = 23, Top Origin = 54, Usable = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: MBAR 1000 +#define MainFormMenuBar 1000 + +// Resource: MENU 1000 +#define MainOptionsMenu 1000 +#define MainOptionsFont 1000 +#define MainOptionsAboutExampleA 1001 + +// Resource: PICT 1200 +#define GlobeBitmap 1200 +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 diff --git a/handera-sdk-105/examples/ExampleB/ExampleB.mcp b/handera-sdk-105/examples/ExampleB/ExampleB.mcp new file mode 100644 index 0000000..fb260c1 Binary files /dev/null and b/handera-sdk-105/examples/ExampleB/ExampleB.mcp differ diff --git a/handera-sdk-105/examples/ExampleB/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleB/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..2be20dc Binary files /dev/null and b/handera-sdk-105/examples/ExampleB/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleB/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleB/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleB/Src/starter.c b/handera-sdk-105/examples/ExampleB/Src/starter.c new file mode 100644 index 0000000..c86c69b --- /dev/null +++ b/handera-sdk-105/examples/ExampleB/Src/starter.c @@ -0,0 +1,478 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project : Example B + * + *****************************************************************************/ + +#include +#include "StarterRsc.h" + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +typedef StarterAppInfoType* StarterAppInfoPtr; + +FontID currentFont = stdFont; +Char helloStr[] = "Hello World"; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_B' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ + + /*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + + /*********************************************************************** + * + * FUNCTION: PrvSetHelloFont + * + * DESCRIPTION: Sets the font and centers the field horizontally + * + * PARAMETERS: + * + * RETURNED: nothing + * + ***********************************************************************/ +static void PrvCenterTextField(FormPtr frmP, FieldPtr fldP, Boolean draw) +{ + RectangleType r, fr; + Int16 stringWidth; + +/*------------------------------------------------------------------------ + * First get the width of the field string in pixels. + *----------------------------------------------------------------------*/ + FntSetFont(FldGetFont(fldP)); + stringWidth = FntCharsWidth(helloStr, StrLen(helloStr)); + +/*------------------------------------------------------------------------ + * Now center the field based on width of string in pixels. + *----------------------------------------------------------------------*/ + FrmGetFormBounds(frmP, &fr); + FrmGetObjectBounds(frmP, FrmGetObjectIndex(frmP, MainHelloField), &r); + + if (draw) + FldEraseField(fldP); + + r.topLeft.x = (fr.extent.x/2) - (stringWidth/2); + FrmSetObjectBounds(frmP, FrmGetObjectIndex(frmP, MainHelloField), &r); + + if (draw) + FldDrawField(fldP); +} + +/*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + ***********************************************************************/ +static void MainFormInit(FormPtr frmP) +{ + FieldPtr fldP; + Char *tmp; + + currentFont = stdFont; + +/*------------------------------------------------------------------------ + * Initialize the field to "Hello World" and set its font + *----------------------------------------------------------------------*/ + fldP = (FieldPtr)GetObjectPtr(MainHelloField); + if ((tmp = FldGetTextPtr(fldP)) != NULL) + MemPtrFree(tmp); + tmp = (Char *)MemPtrNew(StrLen(helloStr) + 1); + StrCopy(tmp, helloStr); + FldSetTextPtr(fldP, tmp); + FldSetFont((FieldPtr)GetObjectPtr(MainHelloField), currentFont); + + PrvCenterTextField(frmP, (FieldPtr)GetObjectPtr(MainHelloField), false);; +} + + + /*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + UInt16 formID; + FormPtr frmP, aboutFrmP; + + frmP = FrmGetActiveForm(); + formID = FrmGetFormId (frmP); + + switch (command) + { + case MainOptionsAboutExampleB : + MenuEraseStatus(0); + aboutFrmP = FrmInitForm (AboutForm); + FrmDoDialog (aboutFrmP); // Display the About Box. + FrmDeleteForm (aboutFrmP); + handled = true; + break; + + case MainOptionsFont : + currentFont = FontSelect(currentFont); + FldSetFont((FieldPtr)GetObjectPtr(MainHelloField), currentFont); + PrvCenterTextField(frmP, (FieldPtr)GetObjectPtr(MainHelloField), true); + handled = true; + break; + } + + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit(frmP); + FrmDrawForm (frmP); + handled = true; + break; + + default: + break; + } + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + +/*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + + /*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: Get the current application's preferences. + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + + return(errNone); +} + +/*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + + /*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + Err error; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + if ((error = AppStart()) != errNone) + return(error); + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + + default: + break; + + } + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} diff --git a/handera-sdk-105/examples/ExampleB/StarterRsc.h b/handera-sdk-105/examples/ExampleB/StarterRsc.h new file mode 100644 index 0000000..7edfd1a --- /dev/null +++ b/handera-sdk-105/examples/ExampleB/StarterRsc.h @@ -0,0 +1,68 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 4:45:36 PM on Wednesday, April 04, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleB\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleB" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) +#define MainGlobeBitMap 1200 //(Left Origin = 50, Top Origin = 50, Bitmap Resource ID = 1200, Usable = 1) +#define MainHelloField 1002 //(Left Origin = 53, Top Origin = 138, Width = 80, Height = 20, Usable = 1, Editable = 0, Underline = 0, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 80, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 0) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutText1Label 1103 //(Left Origin = 23, Top Origin = 54, Usable = 1, Font = Standard) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: MBAR 1000 +#define MainFormMenuBar 1000 + +// Resource: MENU 1000 +#define MainOptionsMenu 1000 +#define MainOptionsFont 1000 +#define MainOptionsAboutExampleB 1001 + +// Resource: PICT 1200 +#define GlobeBitmap 1200 +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: PICT 5296 +#define VGAGlobeBitmap 5296 +// Resource: PICT 1400 +#define VGABigIconBitmap 1400 +// Resource: PICT 1500 +#define VGASmallIconBitmap 1500 +// Resource: PICT 1600 +#define VGABigIconInvertedBitmap 1600 +// Resource: taif 2002 +#define VGABigIconInvertedAppIconFamily 2002 + +// Resource: taif 2001 +#define VGASmallIconAppIconFamily 2001 + +// Resource: taif 2000 +#define VGABigIconAppIconFamily 2000 + +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 diff --git a/handera-sdk-105/examples/ExampleC/ExampleC.mcp b/handera-sdk-105/examples/ExampleC/ExampleC.mcp new file mode 100644 index 0000000..7c41144 Binary files /dev/null and b/handera-sdk-105/examples/ExampleC/ExampleC.mcp differ diff --git a/handera-sdk-105/examples/ExampleC/Rsc/ExampleC.rsrc b/handera-sdk-105/examples/ExampleC/Rsc/ExampleC.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleC/Rsc/Resource.frk/ExampleC.rsrc b/handera-sdk-105/examples/ExampleC/Rsc/Resource.frk/ExampleC.rsrc new file mode 100644 index 0000000..1482156 Binary files /dev/null and b/handera-sdk-105/examples/ExampleC/Rsc/Resource.frk/ExampleC.rsrc differ diff --git a/handera-sdk-105/examples/ExampleC/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleC/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..c926c50 Binary files /dev/null and b/handera-sdk-105/examples/ExampleC/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleC/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleC/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleC/Src/Stub.c b/handera-sdk-105/examples/ExampleC/Src/Stub.c new file mode 100644 index 0000000..a67b2c1 --- /dev/null +++ b/handera-sdk-105/examples/ExampleC/Src/Stub.c @@ -0,0 +1,11 @@ +/****************************************************************************** + * + * File: Stub.c + * + * Project: Example C + * + *****************************************************************************/ +void __Startup__(void) +{ + +} diff --git a/handera-sdk-105/examples/ExampleC/Src/starter.c b/handera-sdk-105/examples/ExampleC/Src/starter.c new file mode 100644 index 0000000..6251bf3 --- /dev/null +++ b/handera-sdk-105/examples/ExampleC/Src/starter.c @@ -0,0 +1,546 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project: Example C + * + *****************************************************************************/ + +#include +#include "StarterRsc.h" + + +/*********************************************************************** + * + * Entry Points + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +typedef StarterAppInfoType* StarterAppInfoPtr; + +FontID currentFont = stdFont; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_5' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ + + +/*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + +/*********************************************************************** + * + * FUNCTION: DrawHelloWorld + * + * DESCRIPTION: This routine prints "Hello World" to the center of the + * window. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void DrawHelloWorld(void) +{ + MemHandle resH; + BitmapPtr resP; + char *str = "Hello World"; + FontID savedFont; + Coord x, y, winWidth, winHeight; + + resH = DmGetResource(bitmapRsc, GlobeBitmap); + ErrFatalDisplayIf(!resH, "Missing bitmap"); + resP = MemHandleLock(resH); + + WinGetWindowExtent(&winWidth, &winHeight); + savedFont = FntSetFont(currentFont); + +/*------------------------------------------------------------------------ + * Draw the globe graphic + *----------------------------------------------------------------------*/ + x = (winWidth/2) - (resP->width/2); + y = (winHeight/2) - (resP->height/2); + WinDrawBitmap(resP, x, y); + +/*------------------------------------------------------------------------ + * Draw String below the globe + *----------------------------------------------------------------------*/ + x = (winWidth/2) - (FntCharsWidth(str, StrLen(str))/2); + y = y + resP->height + FntCharHeight() + 10; + WinDrawChars(str, StrLen(str), x, y); + + FntSetFont(savedFont); + MemPtrUnlock(resP); + DmReleaseResource(resH); +} + +/*********************************************************************** + * + * FUNCTION: EraseHelloWorld + * + * DESCRIPTION: This routine erases "Hello World" from the window. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void EraseHelloWorld(void) +{ + MemHandle resH; + BitmapPtr resP; + char *str = "Hello World"; + FontID savedFont; + Coord x, y, winWidth, winHeight; + + resH = DmGetResource(bitmapRsc, GlobeBitmap); + ErrFatalDisplayIf(!resH, "Missing bitmap"); + resP = MemHandleLock(resH); + + WinGetWindowExtent(&winWidth, &winHeight); + savedFont = FntSetFont(currentFont); + + x = (winWidth/2) - (FntCharsWidth(str, StrLen(str))/2); + y = (winHeight/2) - (resP->height/2); + y = y + resP->height + FntCharHeight() + 10; + WinEraseChars(str, StrLen(str), x, y); + + FntSetFont(savedFont); + MemPtrUnlock(resP); + DmReleaseResource(resH); + +} + + +/*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void MainFormInit(FormPtr /*frmP*/) +{ + DrawHelloWorld(); +} + + +/*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + UInt16 formID; + FormPtr frmP; + FontID newFont; + + switch (command) + { + case MainOptionsAboutExampleC: + MenuEraseStatus(0); // Clear the menu status from the display. + frmP = FrmInitForm (AboutForm); + FrmDoDialog (frmP); // Display the About Box. + FrmDeleteForm (frmP); + handled = true; + break; + + case MainOptionsFont : + formID = (FrmGetFormId (FrmGetActiveForm ())); + newFont = FontSelect(currentFont); + EraseHelloWorld(); + currentFont = newFont; + FrmUpdateForm (formID, frmRedrawUpdateCode); + handled = true; + break; + } + return(handled); +} + + +/*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit( frmP); + FrmDrawForm ( frmP); + handled = true; + break; + + case frmUpdateEvent : + DrawHelloWorld(); + handled = true; + break; + + default: + break; + } + return(handled); +} + + +/*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + +/*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + +/*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: Get the current application's preferences. + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + +/*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr /*cmdPBP*/, UInt16 launchFlags) +{ + Err error; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + error = AppStart(); + if (error) + return error; + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + + default: + break; + + } + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} + diff --git a/handera-sdk-105/examples/ExampleC/StarterRsc.h b/handera-sdk-105/examples/ExampleC/StarterRsc.h new file mode 100644 index 0000000..e54f79a --- /dev/null +++ b/handera-sdk-105/examples/ExampleC/StarterRsc.h @@ -0,0 +1,50 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 2:44:50 PM on Wednesday, March 21, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\dan\examples\ExampleC\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleC" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutTitleLabel 1102 //(Left Origin = 61, Top Origin = 23, Usable = 1, Font = Large) +#define AboutText1Label 1103 //(Left Origin = 23, Top Origin = 54, Usable = 1, Font = Standard) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: MBAR 1000 +#define MainFormMenuBar 1000 + +// Resource: MENU 1000 +#define MainOptionsMenu 1000 +#define MainOptionsFont 1000 +#define MainOptionsAboutExampleC 1001 + +// Resource: PICT 1200 +#define GlobeBitmap 1200 +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 diff --git a/handera-sdk-105/examples/ExampleD/ExampleD.mcp b/handera-sdk-105/examples/ExampleD/ExampleD.mcp new file mode 100644 index 0000000..6f6480a Binary files /dev/null and b/handera-sdk-105/examples/ExampleD/ExampleD.mcp differ diff --git a/handera-sdk-105/examples/ExampleD/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleD/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..46b9da6 Binary files /dev/null and b/handera-sdk-105/examples/ExampleD/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleD/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleD/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleD/Src/starter.c b/handera-sdk-105/examples/ExampleD/Src/starter.c new file mode 100644 index 0000000..2276b63 --- /dev/null +++ b/handera-sdk-105/examples/ExampleD/Src/starter.c @@ -0,0 +1,643 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project : Example D + * + *****************************************************************************/ + +#include +#include "StarterRsc.h" + +#include "vga.h" + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +typedef StarterAppInfoType* StarterAppInfoPtr; + +FontID currentFont = stdFont; +Boolean vgaPresent = false; +Char helloStr[] = "Hello World"; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_D' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + +#define OptionsRotate 1500 + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ + + /*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + + /*********************************************************************** + * + * FUNCTION: PrvMoveObject + * + * DESCRIPTION: This routine moves an object vertically within a form. + * + * PARAMETERS: + * + * RETURNED: nothing + * + ***********************************************************************/ +static void PrvMoveObject(FormPtr frmP, UInt16 objIndex, Coord y_diff, Boolean draw) +{ + RectangleType r; + + FrmGetObjectBounds(frmP, objIndex, &r); + if (draw) + { + RctInsetRectangle(&r, -2); //need to erase the frame as well + WinEraseRectangle(&r, 0); + RctInsetRectangle(&r, 2); + } + r.topLeft.y += y_diff; + FrmSetObjectBounds(frmP, objIndex, &r); +} + +/*********************************************************************** + * + * FUNCTION: PrvCenterObject + * + * DESCRIPTION: This routine centers an object within a form. + * + * PARAMETERS: + * + * RETURNED: nothing + * + ***********************************************************************/ +static void PrvCenterObject(FormPtr frmP, UInt16 objIndex, Boolean draw) +{ + RectangleType r, fr; + +/*------------------------------------------------------------------------ + * Get the frame and bitmap size + *----------------------------------------------------------------------*/ + FrmGetFormBounds(frmP, &fr); + FrmGetObjectBounds(frmP, objIndex, &r); + + if (draw) + { + RctInsetRectangle(&r, -2); //need to erase the frame as well + WinEraseRectangle(&r, 0); + RctInsetRectangle(&r, 2); + } + + r.topLeft.x = (fr.extent.x/2) - (r.extent.x/2); + r.topLeft.y = (fr.extent.y/2) - (r.extent.y/2); + + FrmSetObjectBounds(frmP, objIndex, &r); +} + + /*********************************************************************** + * + * FUNCTION: PrvSetHelloFont + * + * DESCRIPTION: Sets the font and centers the field horizontally + * + * PARAMETERS: + * + * RETURNED: nothing + * + ***********************************************************************/ +static void PrvCenterTextField(FormPtr frmP, FieldPtr fldP, Boolean draw) +{ + RectangleType r, fr; + Int16 stringWidth; + +/*------------------------------------------------------------------------ + * First get the width of the field string in pixels. + *----------------------------------------------------------------------*/ + FntSetFont(FldGetFont(fldP)); + stringWidth = FntCharsWidth(helloStr, StrLen(helloStr)); + +/*------------------------------------------------------------------------ + * Now center the field based on width of string in pixels. + *----------------------------------------------------------------------*/ + FrmGetFormBounds(frmP, &fr); + FrmGetObjectBounds(frmP, FrmGetObjectIndex(frmP, MainHelloField), &r); + + if (draw) + FldEraseField(fldP); + + r.topLeft.x = (fr.extent.x/2) - (stringWidth/2); + FrmSetObjectBounds(frmP, FrmGetObjectIndex(frmP, MainHelloField), &r); + + if (draw) + FldDrawField(fldP); +} + + /*********************************************************************** + * + * FUNCTION: MainFormResize + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static void MainFormResize(FormPtr frmP, Boolean draw) +{ + Coord x, y, y_diff; + RectangleType r; + +/*------------------------------------------------------------------------ + * Get the new extent + *----------------------------------------------------------------------*/ + WinGetDisplayExtent(&x, &y); + +/*------------------------------------------------------------------------ + * Get the old extent + *----------------------------------------------------------------------*/ + FrmGetFormBounds(frmP, &r); + +/*------------------------------------------------------------------------ + * Calculate change in form size. + *----------------------------------------------------------------------*/ + y_diff = y - (r.topLeft.y + r.extent.y); + +/*------------------------------------------------------------------------ + * Resize the form + *----------------------------------------------------------------------*/ + r.extent.y = y; + r.extent.x = x; + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + + PrvCenterObject (frmP, FrmGetObjectIndex(frmP, MainGlobeBitMap), draw); + PrvCenterTextField(frmP, (FieldPtr)GetObjectPtr(MainHelloField), false);; + PrvMoveObject (frmP, FrmGetObjectIndex(frmP, MainHelloField), y_diff, draw); + + if (draw) + FrmDrawForm(frmP); +} + + +/*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + ***********************************************************************/ +static void MainFormInit(FormPtr frmP) +{ + FieldPtr fldP; + Char *tmp; + + currentFont = stdFont; + +/*------------------------------------------------------------------------ + * Initialize the field to "Hello World" and set its font + *----------------------------------------------------------------------*/ + fldP = (FieldPtr)GetObjectPtr(MainHelloField); + if ((tmp = FldGetTextPtr(fldP)) != NULL) + MemPtrFree(tmp); + tmp = (Char *)MemPtrNew(StrLen(helloStr) + 1); + StrCopy(tmp, helloStr); + FldSetTextPtr(fldP, tmp); + FldSetFont((FieldPtr)GetObjectPtr(MainHelloField), currentFont); + + if (vgaPresent) + VgaFormModify(frmP, vgaFormModify160To240); + + MainFormResize(frmP, false); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + UInt16 formID; + FormPtr frmP, aboutFrmP; + VgaScreenModeType screenMode; + VgaRotateModeType rotateMode; + + frmP = FrmGetActiveForm(); + formID = FrmGetFormId (frmP); + + switch (command) + { + case OptionsAboutExampleD: + MenuEraseStatus(0); + if (vgaPresent) + { + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenModeScaleToFit, rotateMode); + } + aboutFrmP = FrmInitForm (AboutForm); + FrmDoDialog (aboutFrmP); // Display the About Box. + FrmDeleteForm (aboutFrmP); + if (vgaPresent) + VgaSetScreenMode(screenMode, rotateMode); + handled = true; + break; + + case OptionsFont : + currentFont = FontSelect(currentFont); + FldSetFont((FieldPtr)GetObjectPtr(MainHelloField), currentFont); + PrvCenterTextField(frmP, (FieldPtr)GetObjectPtr(MainHelloField), true); + handled = true; + break; + + case OptionsRotate : + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenMode1To1, VgaRotateSelect(rotateMode)); + MainFormResize(FrmGetActiveForm(), true); + handled = true; + break; + } + + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit(frmP); + FrmDrawForm (frmP); + handled = true; + break; + + case menuOpenEvent : + if (vgaPresent) + MenuAddItem(OptionsFont, OptionsRotate, 0, "Rotate..."); + handled = true; + break; + + default: + break; + } + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + +/*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + + /*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: Get the current application's preferences. + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + UInt32 version; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + +/*------------------------------------------------------------------------ + * Check for VGA Extension + *----------------------------------------------------------------------*/ + if (_TRGVGAFeaturePresent(&version)) + vgaPresent = true; + else + vgaPresent = false; + + return(errNone); +} + +/*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + + /*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + Err error; + VgaScreenModeType screenMode; + VgaRotateModeType rotateMode; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + if ((error = AppStart()) != errNone) + return(error); + +/*------------------------------------------------------------------------ + * You must set the screen mode before the form is loaded. + *----------------------------------------------------------------------*/ + if (vgaPresent) + { +/*------------------------------------------------------------------------ + * Call VgaGetScreenMode() to get the current rotation. We force the mode + * to 1to1 but want to keep the rotation. + * + * Note: If your app does not support screen rotation, simply call + * + * VgaSetScreenMode(screenMode1To1, rotateModeNone); + * + *----------------------------------------------------------------------*/ + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenMode1To1, rotateMode); + } + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + default: + break; + + } + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} diff --git a/handera-sdk-105/examples/ExampleD/StarterRsc.h b/handera-sdk-105/examples/ExampleD/StarterRsc.h new file mode 100644 index 0000000..d5ef429 --- /dev/null +++ b/handera-sdk-105/examples/ExampleD/StarterRsc.h @@ -0,0 +1,68 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 10:08:10 AM on Thursday, May 03, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleD\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleD" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) +#define MainGlobeBitMap 1200 //(Left Origin = 46, Top Origin = 43, Bitmap Resource ID = 1200, Usable = 1) +#define MainHelloField 1002 //(Left Origin = 40, Top Origin = 145, Width = 80, Height = 12, Usable = 1, Editable = 0, Underline = 0, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 80, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 0) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) +#define AboutText1Label 1103 //(Left Origin = 20, Top Origin = 54, Usable = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: MBAR 1000 +#define MainMenuBar 1000 + +// Resource: MENU 1000 +#define OptionsMenu 1000 +#define OptionsFont 1000 +#define OptionsAboutExampleD 1001 + +// Resource: PICT 1200 +#define GlobeBitmap 1200 +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: PICT 5296 +#define VGAGlobeBitmap 5296 +// Resource: PICT 1400 +#define VGABigIconBitmap 1400 +// Resource: PICT 1500 +#define VGASmallIconBitmap 1500 +// Resource: PICT 1600 +#define VGABigIconInvertedBitmap 1600 +// Resource: taif 2001 +#define VGASmallIconAppIconFamily 2001 + +// Resource: taif 2000 +#define VGABigIconAppIconFamily 2000 + +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 + +// Resource: taif 2002 +#define VGABigIconInvertedAppIconFamily 2002 diff --git a/handera-sdk-105/examples/ExampleE/ExampleE.mcp b/handera-sdk-105/examples/ExampleE/ExampleE.mcp new file mode 100644 index 0000000..c41d401 Binary files /dev/null and b/handera-sdk-105/examples/ExampleE/ExampleE.mcp differ diff --git a/handera-sdk-105/examples/ExampleE/Rsc/HandEra.r b/handera-sdk-105/examples/ExampleE/Rsc/HandEra.r new file mode 100644 index 0000000..371e069 --- /dev/null +++ b/handera-sdk-105/examples/ExampleE/Rsc/HandEra.r @@ -0,0 +1,29 @@ +/*********************************************************************** + * + * Copyright (c) 1999-2001, TRG, All Rights Reserved + * + * PROJECT: HandEra 330 + * + * FILE: HandEra.r + * + * DESCRIPTION: + * + * AUTHOR: John Ehm + * + * DATE: 01/17/01 + * + **********************************************************************/ + + +type 'sKst' { + //Currently no data is stored in resource, need dummy otherwise + //resource is not linked in + unsigned longint; +}; + + +resource 'sKst' (1000, "HandEra Aware") +{ + 0x00000000; + +}; diff --git a/handera-sdk-105/examples/ExampleE/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleE/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..2ce9254 Binary files /dev/null and b/handera-sdk-105/examples/ExampleE/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleE/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleE/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleE/Src/starter.c b/handera-sdk-105/examples/ExampleE/Src/starter.c new file mode 100644 index 0000000..f1ced6c --- /dev/null +++ b/handera-sdk-105/examples/ExampleE/Src/starter.c @@ -0,0 +1,648 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project : Example E + * + *****************************************************************************/ + +#include +#include "StarterRsc.h" + +#include "vga.h" + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +typedef StarterAppInfoType* StarterAppInfoPtr; + +FontID currentFont = stdFont; +Boolean vgaPresent = false; +Char helloStr[] = "Hello World"; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_E' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + +#define OptionsRotate 1500 + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ + + /*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + + /*********************************************************************** + * + * FUNCTION: PrvMoveObject + * + * DESCRIPTION: This routine moves an object vertically within a form. + * + * PARAMETERS: + * + * RETURNED: nothing + * + ***********************************************************************/ +static void PrvMoveObject(FormPtr frmP, UInt16 objIndex, Coord y_diff, Boolean draw) +{ + RectangleType r; + + FrmGetObjectBounds(frmP, objIndex, &r); + if (draw) + { + RctInsetRectangle(&r, -2); //need to erase the frame as well + WinEraseRectangle(&r, 0); + RctInsetRectangle(&r, 2); + } + r.topLeft.y += y_diff; + FrmSetObjectBounds(frmP, objIndex, &r); +} + +/*********************************************************************** + * + * FUNCTION: PrvCenterObject + * + * DESCRIPTION: This routine centers an object within a form. + * + * PARAMETERS: + * + * RETURNED: nothing + * + ***********************************************************************/ +static void PrvCenterObject(FormPtr frmP, UInt16 objIndex, Boolean draw) +{ + RectangleType r, fr; + +/*------------------------------------------------------------------------ + * Get the frame and bitmap size + *----------------------------------------------------------------------*/ + FrmGetFormBounds(frmP, &fr); + FrmGetObjectBounds(frmP, objIndex, &r); + + if (draw) + { + RctInsetRectangle(&r, -2); //need to erase the frame as well + WinEraseRectangle(&r, 0); + RctInsetRectangle(&r, 2); + } + + r.topLeft.x = (fr.extent.x/2) - (r.extent.x/2); + r.topLeft.y = (fr.extent.y/2) - (r.extent.y/2); + + FrmSetObjectBounds(frmP, objIndex, &r); +} + + /*********************************************************************** + * + * FUNCTION: PrvSetHelloFont + * + * DESCRIPTION: Sets the font and centers the field horizontally + * + * PARAMETERS: + * + * RETURNED: nothing + * + ***********************************************************************/ +static void PrvCenterTextField(FormPtr frmP, FieldPtr fldP, Boolean draw) +{ + RectangleType r, fr; + Int16 stringWidth; + +/*------------------------------------------------------------------------ + * First get the width of the field string in pixels. + *----------------------------------------------------------------------*/ + FntSetFont(FldGetFont(fldP)); + stringWidth = FntCharsWidth(helloStr, StrLen(helloStr)); + +/*------------------------------------------------------------------------ + * Now center the field based on width of string in pixels. + *----------------------------------------------------------------------*/ + FrmGetFormBounds(frmP, &fr); + FrmGetObjectBounds(frmP, FrmGetObjectIndex(frmP, MainHelloField), &r); + + if (draw) + FldEraseField(fldP); + + r.topLeft.x = (fr.extent.x/2) - (stringWidth/2); + FrmSetObjectBounds(frmP, FrmGetObjectIndex(frmP, MainHelloField), &r); + + if (draw) + FldDrawField(fldP); +} + + /*********************************************************************** + * + * FUNCTION: MainFormResize + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static void MainFormResize(FormPtr frmP, Boolean draw) +{ + Coord x, y, y_diff; + RectangleType r; + +/*------------------------------------------------------------------------ + * Get the new extent + *----------------------------------------------------------------------*/ + WinGetDisplayExtent(&x, &y); + +/*------------------------------------------------------------------------ + * Get the old extent + *----------------------------------------------------------------------*/ + FrmGetFormBounds(frmP, &r); + +/*------------------------------------------------------------------------ + * Calculate change in form size. + *----------------------------------------------------------------------*/ + y_diff = y - (r.topLeft.y + r.extent.y); + +/*------------------------------------------------------------------------ + * Resize the form + *----------------------------------------------------------------------*/ + r.extent.y = y; + r.extent.x = x; + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + + PrvCenterObject (frmP, FrmGetObjectIndex(frmP, MainGlobeBitMap), draw); + PrvCenterTextField(frmP, (FieldPtr)GetObjectPtr(MainHelloField), false);; + PrvMoveObject (frmP, FrmGetObjectIndex(frmP, MainHelloField), y_diff, draw); + + if (draw) + FrmDrawForm(frmP); +} + + +/*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + ***********************************************************************/ +static void MainFormInit(FormPtr frmP) +{ + FieldPtr fldP; + Char *tmp; + + currentFont = stdFont; + +/*------------------------------------------------------------------------ + * Initialize the field to "Hello World" and set its font + *----------------------------------------------------------------------*/ + fldP = (FieldPtr)GetObjectPtr(MainHelloField); + if ((tmp = FldGetTextPtr(fldP)) != NULL) + MemPtrFree(tmp); + tmp = (Char *)MemPtrNew(StrLen(helloStr) + 1); + StrCopy(tmp, helloStr); + FldSetTextPtr(fldP, tmp); + FldSetFont((FieldPtr)GetObjectPtr(MainHelloField), currentFont); + + if (vgaPresent) + VgaFormModify(frmP, vgaFormModify160To240); + + MainFormResize(frmP, false); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + UInt16 formID; + FormPtr frmP, aboutFrmP; + VgaScreenModeType screenMode; + VgaRotateModeType rotateMode; + + frmP = FrmGetActiveForm(); + formID = FrmGetFormId (frmP); + + switch (command) + { + case OptionsAboutExampleD: + MenuEraseStatus(0); + if (vgaPresent) + { + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenModeScaleToFit, rotateMode); + } + aboutFrmP = FrmInitForm (AboutForm); + FrmDoDialog (aboutFrmP); // Display the About Box. + FrmDeleteForm (aboutFrmP); + if (vgaPresent) + VgaSetScreenMode(screenMode, rotateMode); + handled = true; + break; + + case OptionsFont : + currentFont = FontSelect(currentFont); + FldSetFont((FieldPtr)GetObjectPtr(MainHelloField), currentFont); + PrvCenterTextField(frmP, (FieldPtr)GetObjectPtr(MainHelloField), true); + handled = true; + break; + + case OptionsRotate : + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenMode1To1, VgaRotateSelect(rotateMode)); + MainFormResize(FrmGetActiveForm(), true); + handled = true; + break; + } + + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit(frmP); + FrmDrawForm (frmP); + handled = true; + break; + + case displayExtentChangedEvent : + MainFormResize(FrmGetActiveForm(), true); + handled = true; + break; + + case menuOpenEvent : + if (vgaPresent) + MenuAddItem(OptionsFont, OptionsRotate, 0, "Rotate..."); + handled = true; + break; + + default: + break; + } + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + +/*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + + /*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: Get the current application's preferences. + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + UInt32 version; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + +/*------------------------------------------------------------------------ + * Check for VGA Extension + *----------------------------------------------------------------------*/ + if (_TRGVGAFeaturePresent(&version)) + vgaPresent = true; + else + vgaPresent = false; + + return(errNone); +} + +/*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + + /*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + Err error; + VgaScreenModeType screenMode; + VgaRotateModeType rotateMode; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + if ((error = AppStart()) != errNone) + return(error); + +/*------------------------------------------------------------------------ + * You must set the screen mode before the form is loaded. + *----------------------------------------------------------------------*/ + if (vgaPresent) + { +/*------------------------------------------------------------------------ + * Call VgaGetScreenMode() to get the current rotation. We force the mode + * to 1to1 but want to keep the rotation. + * + * Note: If your app does not support screen rotation, simply call + * + * VgaSetScreenMode(screenMode1To1, rotateModeNone); + * + *----------------------------------------------------------------------*/ + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenMode1To1, rotateMode); + } + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + default: + break; + + } + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} diff --git a/handera-sdk-105/examples/ExampleE/StarterRsc.h b/handera-sdk-105/examples/ExampleE/StarterRsc.h new file mode 100644 index 0000000..daf18c6 --- /dev/null +++ b/handera-sdk-105/examples/ExampleE/StarterRsc.h @@ -0,0 +1,68 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 10:11:42 AM on Thursday, May 03, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleE\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleE" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) +#define MainGlobeBitMap 1200 //(Left Origin = 46, Top Origin = 43, Bitmap Resource ID = 1200, Usable = 1) +#define MainHelloField 1002 //(Left Origin = 40, Top Origin = 145, Width = 80, Height = 12, Usable = 1, Editable = 0, Underline = 0, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 80, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 0) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutText1Label 1103 //(Left Origin = 20, Top Origin = 54, Usable = 1, Font = Standard) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: MBAR 1000 +#define MainMenuBar 1000 + +// Resource: MENU 1000 +#define OptionsMenu 1000 +#define OptionsFont 1000 +#define OptionsAboutExampleD 1001 + +// Resource: PICT 1200 +#define GlobeBitmap 1200 +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: PICT 5296 +#define VGAGlobeBitmap 5296 +// Resource: PICT 1400 +#define VGABigIconBitmap 1400 +// Resource: PICT 1500 +#define VGASmallIconBitmap 1500 +// Resource: PICT 1600 +#define VGABigIconInvertedBitmap 1600 +// Resource: taif 2001 +#define VGASmallIconAppIconFamily 2001 + +// Resource: taif 2000 +#define VGABigIconAppIconFamily 2000 + +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 + +// Resource: taif 2002 +#define VGABigIconInvertedAppIconFamily 2002 diff --git a/handera-sdk-105/examples/ExampleF/ExampleF.mcp b/handera-sdk-105/examples/ExampleF/ExampleF.mcp new file mode 100644 index 0000000..5af6031 Binary files /dev/null and b/handera-sdk-105/examples/ExampleF/ExampleF.mcp differ diff --git a/handera-sdk-105/examples/ExampleF/Rsc/HandEra.r b/handera-sdk-105/examples/ExampleF/Rsc/HandEra.r new file mode 100644 index 0000000..371e069 --- /dev/null +++ b/handera-sdk-105/examples/ExampleF/Rsc/HandEra.r @@ -0,0 +1,29 @@ +/*********************************************************************** + * + * Copyright (c) 1999-2001, TRG, All Rights Reserved + * + * PROJECT: HandEra 330 + * + * FILE: HandEra.r + * + * DESCRIPTION: + * + * AUTHOR: John Ehm + * + * DATE: 01/17/01 + * + **********************************************************************/ + + +type 'sKst' { + //Currently no data is stored in resource, need dummy otherwise + //resource is not linked in + unsigned longint; +}; + + +resource 'sKst' (1000, "HandEra Aware") +{ + 0x00000000; + +}; diff --git a/handera-sdk-105/examples/ExampleF/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleF/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..43446bd Binary files /dev/null and b/handera-sdk-105/examples/ExampleF/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleF/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleF/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleF/Src/starter.c b/handera-sdk-105/examples/ExampleF/Src/starter.c new file mode 100644 index 0000000..4d6edff --- /dev/null +++ b/handera-sdk-105/examples/ExampleF/Src/starter.c @@ -0,0 +1,527 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project : ExampleF + * + *****************************************************************************/ + +#include +#include "StarterRsc.h" + +#include "Silk.h" + +/*********************************************************************** + * + * Entry Points + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +typedef StarterAppInfoType* StarterAppInfoPtr; + +Boolean silkExtensionPresent; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_F' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ +static Err DrawHelloWorld(void); + + +/*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + +/*********************************************************************** + * + * FUNCTION: DrawHelloWorld + * + * DESCRIPTION: This routine prints "Hello World" to the center of the + * window. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Err DrawHelloWorld(void) +{ + WinHandle silkWindow, savedWindow; + MemHandle resH; + BitmapPtr resP; + Coord x, y, winWidth, winHeight; + +/*------------------------------------------------------------------------ + * Get the WinHandle to the silkscreen window + *----------------------------------------------------------------------*/ + if ((silkWindow = SilkGetWindow()) == NULL) + return(-1); + + savedWindow = WinSetDrawWindow(silkWindow); + + if (SilkWindowMaximized()) + { + resH = DmGetResource(bitmapRsc, GlobeBitmap); + ErrFatalDisplayIf(!resH, "Missing bitmap"); + resP = MemHandleLock(resH); + +/*------------------------------------------------------------------------ + * Determine the size of the silkscreen area so we can center the globe. + *----------------------------------------------------------------------*/ + WinGetWindowExtent(&winWidth, &winHeight); + +/*------------------------------------------------------------------------ + * Draw the globe graphic + *----------------------------------------------------------------------*/ + x = (winWidth/2) - (resP->width/2); + x -= 20; //OK, fudge a little so we don't erase the down arrow. + y = (winHeight/2) - (resP->height/2); + WinPaintBitmap(resP, x, y); + + MemPtrUnlock(resP); + DmReleaseResource(resH); + + } + else + { + FntSetFont(stdFont); + WinDrawChars("Hello World", 11, 50, 3); + } + + WinSetDrawWindow(savedWindow); + + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void MainFormInit(FormPtr /*frmP*/) +{ +} + + +/*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + FormPtr frmP; + + switch (command) + { + case MainOptionsAboutExampleF: + MenuEraseStatus(0); // Clear the menu status from the display. + frmP = FrmInitForm (AboutForm); + FrmDoDialog (frmP); // Display the About Box. + FrmDeleteForm (frmP); + handled = true; + break; + + } + return(handled); +} + + +/*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case ctlSelectEvent : + switch(eventP->data.ctlSelect.controlID) + { + case MainHelloWorldButton : + if (!silkExtensionPresent) + FrmAlert(SilkExtNotFoundAlert); + else + if (DrawHelloWorld() != errNone) + FrmAlert(SilkDrawErrorAlert); + + break; + } + break; + + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit( frmP); + FrmDrawForm ( frmP); + handled = true; + break; + + default: + break; + } + return(handled); +} + + +/*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + +/*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + +/*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: Get the current application's preferences. + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + UInt32 version; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + + if (_TRGSilkFeaturePresent(&version)) + silkExtensionPresent = true; + else + silkExtensionPresent = false; + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + +/*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr /*cmdPBP*/, UInt16 launchFlags) +{ + Err error; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + error = AppStart(); + if (error) + return error; + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + + default: + break; + + } + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} + diff --git a/handera-sdk-105/examples/ExampleF/StarterRsc.h b/handera-sdk-105/examples/ExampleF/StarterRsc.h new file mode 100644 index 0000000..b81de30 --- /dev/null +++ b/handera-sdk-105/examples/ExampleF/StarterRsc.h @@ -0,0 +1,72 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 6:29:08 PM on Friday, March 23, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleF\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleF" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) +#define MainHelloWorldButton 1001 //(Left Origin = 50, Top Origin = 75, Width = 60, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutText1Label 1103 //(Left Origin = 23, Top Origin = 54, Usable = 1, Font = Standard) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: Talt 1000 +#define SilkExtNotFoundAlert 1000 +#define SilkExtNotFoundOK 0 + +// Resource: Talt 1100 +#define SilkDrawErrorAlert 1100 +#define SilkDrawErrorOK 0 + +// Resource: MBAR 1000 +#define MainFormMenuBar 1000 + +// Resource: MENU 1000 +#define MainOptionsMenu 1000 +#define MainOptionsAboutExampleF 1000 + +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: PICT 1400 +#define VGABigIconBitmap 1400 +// Resource: PICT 1500 +#define VGASmallIconBitmap 1500 +// Resource: PICT 1200 +#define GlobeBitmap 1200 +// Resource: PICT 1600 +#define VGABigIconInvertedBitmap 1600 +// Resource: taif 2002 +#define VGABigIconInvertedAppIconFamily 2002 + +// Resource: taif 2001 +#define VGASmallIconAppIconFamily 2001 + +// Resource: taif 2000 +#define VGABigIconAppIconFamily 2000 + +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 diff --git a/handera-sdk-105/examples/ExampleG/Bitmaps/silk-1bit.bmp b/handera-sdk-105/examples/ExampleG/Bitmaps/silk-1bit.bmp new file mode 100644 index 0000000..ce44140 Binary files /dev/null and b/handera-sdk-105/examples/ExampleG/Bitmaps/silk-1bit.bmp differ diff --git a/handera-sdk-105/examples/ExampleG/Bitmaps/silk-2bit.bmp b/handera-sdk-105/examples/ExampleG/Bitmaps/silk-2bit.bmp new file mode 100644 index 0000000..6ee94d8 Binary files /dev/null and b/handera-sdk-105/examples/ExampleG/Bitmaps/silk-2bit.bmp differ diff --git a/handera-sdk-105/examples/ExampleG/Bitmaps/silk_inv-1bit.bmp b/handera-sdk-105/examples/ExampleG/Bitmaps/silk_inv-1bit.bmp new file mode 100644 index 0000000..9aa8151 Binary files /dev/null and b/handera-sdk-105/examples/ExampleG/Bitmaps/silk_inv-1bit.bmp differ diff --git a/handera-sdk-105/examples/ExampleG/Bitmaps/silk_inv-2bit.bmp b/handera-sdk-105/examples/ExampleG/Bitmaps/silk_inv-2bit.bmp new file mode 100644 index 0000000..458eabe Binary files /dev/null and b/handera-sdk-105/examples/ExampleG/Bitmaps/silk_inv-2bit.bmp differ diff --git a/handera-sdk-105/examples/ExampleG/ExampleG.mcp b/handera-sdk-105/examples/ExampleG/ExampleG.mcp new file mode 100644 index 0000000..ac8a744 Binary files /dev/null and b/handera-sdk-105/examples/ExampleG/ExampleG.mcp differ diff --git a/handera-sdk-105/examples/ExampleG/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleG/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..ebb9e50 Binary files /dev/null and b/handera-sdk-105/examples/ExampleG/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleG/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleG/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleG/Src/starter.c b/handera-sdk-105/examples/ExampleG/Src/starter.c new file mode 100644 index 0000000..8ec24ba --- /dev/null +++ b/handera-sdk-105/examples/ExampleG/Src/starter.c @@ -0,0 +1,743 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project : ExampleG + * + *****************************************************************************/ + +#include +#include "StarterRsc.h" + +#include "Silk.h" + +/*********************************************************************** + * + * Entry Points + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +typedef StarterAppInfoType* StarterAppInfoPtr; + +Boolean silkPresent; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_G' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +#define NUM_NEW_BUTTONS 11 + +#define KEYPAD_TOPX 141 +#define KEYPAD_TOPY 21 +#define BUTTON_WIDTH 14 +#define BUTTON_HEIGHT 14 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ + + +/*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + +/*********************************************************************** + * + * FUNCTION: SetNewButtons + * + * DESCRIPTION: Sets up the numeric keypad structure. + * + * PARAMETERS: + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void SetNewButtons(PenBtnListType *buttonList) +{ + UInt16 index, i; + + index = buttonList->numButtons; + +/*------------------------------------------------------------------------ + * Look for the numeric keyboard button. Simply set the width to 0 for this + * example. A complete app would competely remove it. + *----------------------------------------------------------------------*/ + for (i = 0;i < index; i++) + { + if (buttonList->buttons[i].asciiCode == vchrKeyboardNumeric) + { + buttonList->buttons[i].boundsR.extent.x = 1; + buttonList->buttons[i].boundsR.extent.y = 1; + } + } + +/*------------------------------------------------------------------------ + * '1' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+0].boundsR.topLeft.x = KEYPAD_TOPX ; + buttonList->buttons[index+0].boundsR.topLeft.y = KEYPAD_TOPY; + buttonList->buttons[index+0].boundsR.extent.x = BUTTON_WIDTH; + buttonList->buttons[index+0].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+0].asciiCode = '1'; + buttonList->buttons[index+0].keyCode = 0; + buttonList->buttons[index+0].modifiers = 0; + +/*------------------------------------------------------------------------ + * '2' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+1].boundsR.topLeft.x = KEYPAD_TOPX + BUTTON_WIDTH; + buttonList->buttons[index+1].boundsR.topLeft.y = KEYPAD_TOPY; + buttonList->buttons[index+1].boundsR.extent.x = BUTTON_WIDTH; + buttonList->buttons[index+1].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+1].asciiCode = '2'; + buttonList->buttons[index+1].keyCode = 0; + buttonList->buttons[index+1].modifiers = 0; + +/*------------------------------------------------------------------------ + * '3' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+2].boundsR.topLeft.x = KEYPAD_TOPX + (BUTTON_WIDTH*2); + buttonList->buttons[index+2].boundsR.topLeft.y = KEYPAD_TOPY; + buttonList->buttons[index+2].boundsR.extent.x = BUTTON_WIDTH; + buttonList->buttons[index+2].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+2].asciiCode = '3'; + buttonList->buttons[index+2].keyCode = 0; + buttonList->buttons[index+2].modifiers = 0; + +/*------------------------------------------------------------------------ + * '4' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+3].boundsR.topLeft.x = KEYPAD_TOPX; + buttonList->buttons[index+3].boundsR.topLeft.y = KEYPAD_TOPY + BUTTON_HEIGHT; + buttonList->buttons[index+3].boundsR.extent.x = BUTTON_WIDTH; + buttonList->buttons[index+3].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+3].asciiCode = '4'; + buttonList->buttons[index+3].keyCode = 0; + buttonList->buttons[index+3].modifiers = 0; + +/*------------------------------------------------------------------------ + * '5' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+4].boundsR.topLeft.x = KEYPAD_TOPX + BUTTON_WIDTH; + buttonList->buttons[index+4].boundsR.topLeft.y = KEYPAD_TOPY + BUTTON_HEIGHT; + buttonList->buttons[index+4].boundsR.extent.x = BUTTON_WIDTH; + buttonList->buttons[index+4].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+4].asciiCode = '5'; + buttonList->buttons[index+4].keyCode = 0; + buttonList->buttons[index+4].modifiers = 0; + +/*------------------------------------------------------------------------ + * '6' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+5].boundsR.topLeft.x = KEYPAD_TOPX + (BUTTON_WIDTH*2); + buttonList->buttons[index+5].boundsR.topLeft.y = KEYPAD_TOPY + BUTTON_HEIGHT; + buttonList->buttons[index+5].boundsR.extent.x = BUTTON_WIDTH; + buttonList->buttons[index+5].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+5].asciiCode = '6'; + buttonList->buttons[index+5].keyCode = 0; + buttonList->buttons[index+5].modifiers = 0; + +/*------------------------------------------------------------------------ + * '7' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+6].boundsR.topLeft.x = KEYPAD_TOPX; + buttonList->buttons[index+6].boundsR.topLeft.y = KEYPAD_TOPY + (BUTTON_HEIGHT*2); + buttonList->buttons[index+6].boundsR.extent.x = BUTTON_WIDTH; + buttonList->buttons[index+6].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+6].asciiCode = '7'; + buttonList->buttons[index+6].keyCode = 0; + buttonList->buttons[index+6].modifiers = 0; + +/*------------------------------------------------------------------------ + * '8' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+7].boundsR.topLeft.x = KEYPAD_TOPX + BUTTON_WIDTH; + buttonList->buttons[index+7].boundsR.topLeft.y = KEYPAD_TOPY + (BUTTON_HEIGHT*2); + buttonList->buttons[index+7].boundsR.extent.x = BUTTON_WIDTH; + buttonList->buttons[index+7].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+7].asciiCode = '8'; + buttonList->buttons[index+7].keyCode = 0; + buttonList->buttons[index+7].modifiers = 0; + +/*------------------------------------------------------------------------ + * '9' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+8].boundsR.topLeft.x = KEYPAD_TOPX + (BUTTON_WIDTH*2); + buttonList->buttons[index+8].boundsR.topLeft.y = KEYPAD_TOPY + (BUTTON_HEIGHT*2); + buttonList->buttons[index+8].boundsR.extent.x = BUTTON_WIDTH; + buttonList->buttons[index+8].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+8].asciiCode = '9'; + buttonList->buttons[index+8].keyCode = 0; + buttonList->buttons[index+8].modifiers = 0; + +/*------------------------------------------------------------------------ + * '0' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+9].boundsR.topLeft.x = KEYPAD_TOPX; + buttonList->buttons[index+9].boundsR.topLeft.y = KEYPAD_TOPY + (BUTTON_HEIGHT*3); + buttonList->buttons[index+9].boundsR.extent.x = BUTTON_WIDTH * 2; + buttonList->buttons[index+9].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+9].asciiCode = '0'; + buttonList->buttons[index+9].keyCode = 0; + buttonList->buttons[index+9].modifiers = 0; + +/*------------------------------------------------------------------------ + * '.' + *----------------------------------------------------------------------*/ + buttonList->buttons[index+10].boundsR.topLeft.x = KEYPAD_TOPX + (BUTTON_WIDTH*2); + buttonList->buttons[index+10].boundsR.topLeft.y = KEYPAD_TOPY + (BUTTON_HEIGHT*3); + buttonList->buttons[index+10].boundsR.extent.x = BUTTON_WIDTH; + buttonList->buttons[index+10].boundsR.extent.y = BUTTON_HEIGHT; + buttonList->buttons[index+10].asciiCode = '.'; + buttonList->buttons[index+10].keyCode = 0; + buttonList->buttons[index+10].modifiers = 0; + + buttonList->numButtons += NUM_NEW_BUTTONS; + +} + +/*********************************************************************** + * + * FUNCTION: SetTemplate + * + * DESCRIPTION: This routine changes the template to our template + * + * PARAMETERS: + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void SetTemplate(void) +{ + MemHandle normalH, invertedH; + BitmapPtr normal, inverted; + RectangleType alpha, numeric; + UInt16 numNewButtons; + PenBtnListType *currentPtr, *newPtr; + UInt16 currentSize, newSize; + +/*------------------------------------------------------------------------ + * First draw the new silscreen template + *----------------------------------------------------------------------*/ + normalH = DmGetResource(bitmapRsc, NormalSilkBitmapFamily); + ErrFatalDisplayIf(!normalH, "Missing normal bitmap"); + normal = MemHandleLock(normalH); + + invertedH = DmGetResource(bitmapRsc, InvertedSilkBitmapFamily); + ErrFatalDisplayIf(!invertedH, "Missing inverted bitmap"); + inverted = MemHandleLock(invertedH); + + SilkSetTemplateBitmaps(normal, inverted, NULL, NULL); + SilkMaximizeWindow(); + + MemPtrUnlock(normal); + DmReleaseResource(normalH); + MemPtrUnlock(inverted); + DmReleaseResource(invertedH); + +/*------------------------------------------------------------------------ + * The numeric graffiti area can not be removed, so make its width 1, which + * will effectively remove it. + *----------------------------------------------------------------------*/ + SilkGetAreas(&alpha, &numeric); + numeric.extent.x = 1; + SilkSetAreas(&alpha, &numeric); + +/*------------------------------------------------------------------------ + * First get the number of silk buttons so we know how much to allocate, + * with our additional buttons. + *----------------------------------------------------------------------*/ + currentSize = SilkGetButtonListSize(true); + + if ((currentPtr = MemPtrNew(currentSize)) == NULL) + { + ErrFatalDisplay("Allcoate Errror"); + return; + } + + SilkGetButtonList(currentPtr, true); + +/*------------------------------------------------------------------------ + * Allocate space for new button list. + *----------------------------------------------------------------------*/ + numNewButtons = currentPtr->numButtons + NUM_NEW_BUTTONS; + newSize = sizeof(PenBtnListType) + (sizeof(PenBtnInfoType) * (numNewButtons - 1)); + + if ((newPtr = MemPtrNew(newSize)) == NULL) + { + MemPtrFree(currentPtr); + ErrFatalDisplay("Allcoate Errror"); + return; + } + + MemMove(newPtr, currentPtr, currentSize); + + SetNewButtons(newPtr); + SilkSetButtonList(newPtr, true); + +/*------------------------------------------------------------------------ + * Since the button list is copied by the system, we can free our copy. + *----------------------------------------------------------------------*/ + MemPtrFree(currentPtr); + MemPtrFree(newPtr); + +} + +/*********************************************************************** + * + * FUNCTION: ResetTemplate + * + * DESCRIPTION: This routine restores the defaul template, areas and + * silk buttons. + * + * PARAMETERS: + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void ResetTemplate(void) +{ + SilkRestoreDefaultTemplates(); + SilkMaximizeWindow(); +} + +/*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void MainFormInit(FormPtr /*frmP*/) +{ +} + + +/*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + FormPtr frmP; + + switch (command) + { + case MainOptionsAboutExampleG : + MenuEraseStatus(0); // Clear the menu status from the display. + frmP = FrmInitForm (AboutForm); + FrmDoDialog (frmP); // Display the About Box. + FrmDeleteForm (frmP); + handled = true; + break; + + } + return(handled); +} + + +/*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case ctlSelectEvent : + switch(eventP->data.ctlSelect.controlID) + { + case MainSetTemplateButton : + if (!silkPresent) + FrmAlert(SilkExtNotFoundAlert); + else + SetTemplate(); + break; + + case MainResetTemplateButton : + if (!silkPresent) + FrmAlert(SilkExtNotFoundAlert); + else + ResetTemplate(); + break; + } + break; + + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit( frmP); + FrmDrawForm ( frmP); + handled = true; + break; + + default: + break; + } + return(handled); +} + + +/*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + +/*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + +/*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: Get the current application's preferences. + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + UInt32 version; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + + if (_TRGSilkFeaturePresent(&version)) + silkPresent = true; + else + silkPresent = false; + + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + +/*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr /*cmdPBP*/, UInt16 launchFlags) +{ + Err error; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + error = AppStart(); + if (error) + return error; + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + + default: + break; + + } + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} + diff --git a/handera-sdk-105/examples/ExampleG/StarterRsc.h b/handera-sdk-105/examples/ExampleG/StarterRsc.h new file mode 100644 index 0000000..262afc0 --- /dev/null +++ b/handera-sdk-105/examples/ExampleG/StarterRsc.h @@ -0,0 +1,81 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 4:38:50 PM on Saturday, March 24, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleG\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleG" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) +#define MainSetTemplateButton 1001 //(Left Origin = 50, Top Origin = 75, Width = 60, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) +#define MainResetTemplateButton 1002 //(Left Origin = 40, Top Origin = 110, Width = 80, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutText1Label 1103 //(Left Origin = 23, Top Origin = 54, Usable = 1, Font = Standard) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: Talt 1000 +#define SilkExtNotFoundAlert 1000 +#define SilkExtNotFoundOK 0 + +// Resource: MBAR 1000 +#define MainFormMenuBar 1000 + +// Resource: MENU 1000 +#define MainOptionsMenu 1000 +#define MainOptionsAboutExampleG 1000 + +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: PICT 1400 +#define VGABigIconBitmap 1400 +// Resource: PICT 1500 +#define VGASmallIconBitmap 1500 +// Resource: PICT 1600 +#define Silk1Bitmap 1600 +// Resource: PICT 1700 +#define Silk2Bitmap 1700 +// Resource: PICT 1800 +#define Silk3Bitmap 1800 +// Resource: PICT 1900 +#define Silk4Bitmap 1900 +// Resource: PICT 2000 +#define VGABigIconInvertedBitmap 2000 +// Resource: tbmf 3000 +#define InvertedSilkBitmapFamily 3000 + +// Resource: tbmf 3100 +#define NormalSilkBitmapFamily 3100 + +// Resource: taif 2001 +#define VGASmallIconAppIconFamily 2001 + +// Resource: taif 2000 +#define VGABigIconAppIconFamily 2000 + +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 + +// Resource: taif 2002 +#define VGABigIconInvertedAppIconFamily 2002 diff --git a/handera-sdk-105/examples/ExampleH/ExampleH.mcp b/handera-sdk-105/examples/ExampleH/ExampleH.mcp new file mode 100644 index 0000000..4b9cf00 Binary files /dev/null and b/handera-sdk-105/examples/ExampleH/ExampleH.mcp differ diff --git a/handera-sdk-105/examples/ExampleH/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleH/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..9087634 Binary files /dev/null and b/handera-sdk-105/examples/ExampleH/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleH/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleH/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleH/Src/MainForm.h b/handera-sdk-105/examples/ExampleH/Src/MainForm.h new file mode 100644 index 0000000..8f19473 --- /dev/null +++ b/handera-sdk-105/examples/ExampleH/Src/MainForm.h @@ -0,0 +1,17 @@ +/****************************************************************************** + * + * File: MainForm.h + * + * Project : Example H + * + *****************************************************************************/ +#ifndef _MAINFORM_H_ +#define _MAINFORM_H_ + +#include + +Boolean MainFormHandleEvent (EventPtr eventP); + +#endif + + diff --git a/handera-sdk-105/examples/ExampleH/Src/mainform.c b/handera-sdk-105/examples/ExampleH/Src/mainform.c new file mode 100644 index 0000000..8984be3 --- /dev/null +++ b/handera-sdk-105/examples/ExampleH/Src/mainform.c @@ -0,0 +1,707 @@ +/****************************************************************************** + * + * File: MainForm.c + * + * Project : Example H + * + *****************************************************************************/ + +#include +#include +#include "StarterRsc.h" + +#include "Vga.h" +#include "Audio.h" +#include "MainForm.h" + +/*********************************************************************** + * + * Local Types + * + ***********************************************************************/ + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ +extern Boolean vgaPresent; + +/*********************************************************************** + * + * Local Constants + * + ***********************************************************************/ +#define maxTableItems 13 +#define tblNameCol 0x00 + +/*********************************************************************** + * + * Local Functions + * + ***********************************************************************/ +static void *GetObjectPtr (UInt16 objectID); +static void PrvMoveObject (FormPtr frmP, UInt16 objIndex, Coord y_diff, Boolean draw); +static void PrvResizeObject (FormPtr frmP, UInt16 objIndex, Coord y_diff, Boolean draw); +static void TableDrawItem (void * tableP, Int16 row, Int16 column, RectanglePtr bounds); +static void MainFormScrollLines(Int16 lines, Boolean force_redraw); + + +/*********************************************************************** + * + * Local Variables + * + ***********************************************************************/ +static FontID currentFont; +static Int16 numTableItems; +static Int16 currentSelection; + + /*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + +/*********************************************************************** + * + * FUNCTION: PrvFrmGetGSI + * + * DESCRIPTION: FrmGetObjectIndex() does not work for the graffiti shift + * indicator. Therefore, we must do it ourselves. + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static UInt16 PrvFrmGetGSI(FormPtr frmP) +{ + UInt16 i, numObjects; + + numObjects = FrmGetNumberOfObjects(frmP); + + for (i=0; i 0) + currentSelection --; + else + { + if (valueP > minP) + MainFormScrollLines(-1, true); + } + } + + TblSelectItem(GetObjectPtr(MainAppTable), currentSelection, 0); +} + +/*********************************************************************** + * FUNCTION: HandleNextKey + * DESCRIPTION: + * PARAMETERS: + * RETURNED: + ***********************************************************************/ +static void HandleNextKey(void) +{ + ScrollBarPtr barP; + Int16 valueP, minP, maxP, pageSizeP; + + barP = GetObjectPtr(MainAppScrollBar); + SclGetScrollBar(barP, &valueP, &minP, &maxP, &pageSizeP); + + if (currentSelection == -1) + currentSelection = 0; + else + { + if (currentSelection < pageSizeP - 1) + currentSelection ++; + else + { + if (valueP < maxP) + MainFormScrollLines(1, true); + } + } + + TblSelectItem(GetObjectPtr(MainAppTable), currentSelection, 0); +} + + + /*********************************************************************** + * FUNCTION: TableDrawItem + * DESCRIPTION: + * PARAMETERS: + * RETURNED: + ***********************************************************************/ +static void TableDrawItem(void * tableP, Int16 row, Int16 column, RectanglePtr bounds) +{ + FontID saveID; + Int16 valueP, minP, maxP, pageSizeP; + ScrollBarPtr barP; + Char buf[20]; + + WinEraseRectangle(bounds, 0); + + barP = GetObjectPtr(MainAppScrollBar); + SclGetScrollBar(barP, &valueP, &minP, &maxP, &pageSizeP); + row += valueP; + + if(row < numTableItems) + { + StrPrintF(buf, "Line %d", row + 1); + + saveID = FntSetFont(currentFont); + WinDrawTruncChars(buf, StrLen(buf), bounds->topLeft.x, bounds->topLeft.y, TblGetColumnWidth((TablePtr) tableP, column)); + FntSetFont(saveID); + } +} + + + + /*********************************************************************** + * FUNCTION: TableLoad + * DESCRIPTION: + * PARAMETERS: + * RETURNED: + ***********************************************************************/ +static void TableLoad(Int16 listOffset) +{ + ScrollBarPtr barP; + Int16 listItems = 0; + RectangleType rect; + Int16 running_total, row_height; + Int16 tblRows, row, visibleRows; + TablePtr tableP; + + tableP = GetObjectPtr(MainAppTable); + tblRows = TblGetNumberOfRows(tableP); + + TblSetColumnUsable (tableP, tblNameCol, true); + + FntSetFont(currentFont); + row_height = FntLineHeight(); + TblGetBounds(tableP, &rect); + running_total = 0; + visibleRows = 0; + + for(row=0; row< tblRows; row++) + { + TblSetRowHeight(tableP, row, row_height); + + running_total += row_height; + + if(row < numTableItems) + TblSetRowUsable(tableP, row, running_total < rect.extent.y); + else + TblSetRowUsable(tableP, row, false); + + if (running_total < rect.extent.y) + visibleRows++; + + TblMarkRowInvalid(tableP, row); + } + + barP = GetObjectPtr(MainAppScrollBar); + if(numTableItems > visibleRows) + SclSetScrollBar(barP, listOffset, 0, numTableItems - visibleRows, visibleRows); + else + SclSetScrollBar(barP, 0, 0, 0, numTableItems); + +} + + /*********************************************************************** + * FUNCTION: TableInit + * DESCRIPTION: + * PARAMETERS: + * RETURNED: + ***********************************************************************/ +static void TableInit(void) +{ + ScrollBarPtr barP; + Int16 tblRows, row, row_height; + TablePtr tableP; + + currentSelection = -1; + + tableP = GetObjectPtr(MainAppTable); + tblRows = TblGetNumberOfRows(tableP); + + FntSetFont(currentFont); + + row_height = FntLineHeight(); + + for(row=0; row< tblRows; row++) + { + TblSetItemStyle(tableP, row, tblNameCol, customTableItem); + TblSetRowHeight(tableP, row, row_height); + } + +/*------------------------------------------------------------------------ + * Set the callback routine that draws the Name column. + *----------------------------------------------------------------------*/ + TblSetCustomDrawProcedure (tableP, tblNameCol, TableDrawItem); + + barP = GetObjectPtr(MainAppScrollBar); + SclSetScrollBar(barP, 0, 0, 0, 0); + +} + + /*********************************************************************** + * FUNCTION: + * DESCRIPTION: + * PARAMETERS: + * RETURNED: + * REVISION HISTORY: + ***********************************************************************/ +static void MainFormScroll(Int16 newValue, Int16 oldValue, Boolean force_redraw) +{ + TablePtr tableP; + + tableP = GetObjectPtr(MainAppTable); + + TblUnhighlightSelection(tableP); + + if(oldValue != newValue) + { + TableLoad(newValue); + + if(force_redraw) + TblDrawTable(tableP); + } + +} + +/*********************************************************************** + * FUNCTION: + * DESCRIPTION: + * PARAMETERS: + * RETURNED: + * REVISION HISTORY: + ***********************************************************************/ +static void MainFormScrollLines(Int16 lines, Boolean force_redraw) +{ + ScrollBarPtr barP; + Int16 valueP, minP, maxP, pageSizeP; + Int16 newValue; + + barP = GetObjectPtr(MainAppScrollBar); + SclGetScrollBar(barP, &valueP, &minP, &maxP, &pageSizeP); + + TblUnhighlightSelection(GetObjectPtr(MainAppTable)); + + //scroll up + if(lines < 0) + { + //we are at the start + if(valueP == minP) + return; + + newValue = valueP + lines; + if(newValue < minP) + newValue = minP; + } + else + { + if(valueP == maxP) + return; + + newValue = valueP + lines; + if(newValue > maxP) + newValue = maxP; + } + + SclSetScrollBar(barP, newValue, minP, maxP, pageSizeP); + MainFormScroll(newValue, valueP, force_redraw); + +} + + + /*********************************************************************** + * + * FUNCTION: MainFormResize + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static void MainFormResize(FormPtr frmP, Boolean draw) +{ + Int16 valueP, minP, maxP, pageSizeP; + ScrollBarPtr barP; + UInt16 objIdx; + Coord x, y; + Coord y_diff; + RectangleType r, erase_rect; + +/*------------------------------------------------------------------------ + * Get the new extent + *----------------------------------------------------------------------*/ + WinGetDisplayExtent(&x, &y); + +/*------------------------------------------------------------------------ + * Get the old extent + *----------------------------------------------------------------------*/ + FrmGetFormBounds(frmP, &r); + +/*------------------------------------------------------------------------ + * Calculate change + *----------------------------------------------------------------------*/ + y_diff = y - (r.topLeft.y + r.extent.y); + +/*------------------------------------------------------------------------ + * If the silkscreen was maximized, erase the area under maxmized silkscreen + *----------------------------------------------------------------------*/ + if (draw && (y_diff < 0)) + { + erase_rect = r; + erase_rect.topLeft.y = r.extent.y + y_diff; + erase_rect.extent.y = -y_diff; + WinEraseRectangle(&erase_rect, 0); + } + +/*------------------------------------------------------------------------ + * Resize the form + *----------------------------------------------------------------------*/ + r.extent.y += y_diff; + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + +/*------------------------------------------------------------------------ + * Move Bottom Controls Button + *----------------------------------------------------------------------*/ + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, MainHelpButton), y_diff, draw); + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, MainTextField), y_diff, draw); + +/*------------------------------------------------------------------------ + * Move the GSI (graffiti shift indicator) + * Need to set the GSI's location as well as it's location on the form + *----------------------------------------------------------------------*/ + objIdx = PrvFrmGetGSI(frmP); + PrvMoveObject (frmP, objIdx, y_diff, draw); + FrmGetObjectPosition(frmP, objIdx, &x, &y); + GsiSetLocation (x, y+y_diff); + +/*------------------------------------------------------------------------ + * Resize Scrollbar + *----------------------------------------------------------------------*/ + PrvResizeObject(frmP, FrmGetObjectIndex(frmP, MainAppScrollBar), y_diff, draw); + +/*------------------------------------------------------------------------ + * Resize the table + *----------------------------------------------------------------------*/ + PrvResizeObject(frmP, FrmGetObjectIndex(frmP, MainAppTable), y_diff, draw); + + if (draw) + { + barP = GetObjectPtr(MainAppScrollBar); + SclGetScrollBar(barP, &valueP, &minP, &maxP, &pageSizeP); + + TableLoad(valueP); + FrmDrawForm(frmP); + + currentSelection = -1; + } +} + + + /*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + ***********************************************************************/ +static void MainFormInit(FormPtr frmP) +{ + TableInit(); + + numTableItems = maxTableItems; + currentFont = stdFont; + + if (vgaPresent) + { + currentFont = VgaBaseToVgaFont(currentFont); + VgaTableUseBaseFont((TablePtr)GetObjectPtr(MainAppTable), false); + VgaFormModify(frmP, vgaFormModify160To240); + MainFormResize(frmP, false); + } + + TableLoad(0); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + UInt16 formID; + FontID newFont; + FormPtr frmP; + VgaScreenModeType screenMode; + VgaRotateModeType rotateMode; + + formID = (FrmGetFormId (FrmGetActiveForm ())); + + switch (command) + { + case MainOptionsAboutExampleH: + MenuEraseStatus(0); + if (vgaPresent) + { + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenModeScaleToFit, rotateMode); + } + frmP = FrmInitForm (AboutForm); + FrmDoDialog (frmP); // Display the About Box. + FrmDeleteForm (frmP); + if (vgaPresent) + VgaSetScreenMode(screenMode, rotateMode); + handled = true; + break; + + case MainOptionsFont : + TblUnhighlightSelection(GetObjectPtr(MainAppTable)); + currentSelection = -1; + newFont = FontSelect(currentFont); +/*------------------------------------------------------------------------ + * Note: There is a bug in the OS which causes large Table Fonts to not + * highlight properly when selected. The work around is to implement + * the selection yourself. For simplicity sake, this example + * does not do this. + *----------------------------------------------------------------------*/ + currentFont = newFont; + if (vgaPresent) + { + if (VgaIsVgaFont(currentFont)) + VgaTableUseBaseFont((TablePtr)GetObjectPtr(MainAppTable), false); + else + VgaTableUseBaseFont((TablePtr)GetObjectPtr(MainAppTable), true); + } + MainFormResize(FrmGetActiveForm(), true); + handled = true; + break; + } + + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + ***********************************************************************/ +Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + ScrollBarPtr barP; + Int16 valueP, minP, maxP, pageSizeP; + + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case ctlSelectEvent : + switch(eventP->data.ctlSelect.controlID) + { + case MainHelpButton : + FrmHelp(HelpString); + handled = true; + break; + } + break; + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit(frmP); + FrmDrawForm (frmP); + handled = true; + break; + + case displayExtentChangedEvent : + MainFormResize(FrmGetActiveForm(), true); + break; + + case frmCloseEvent : + handled = true; + break; + + case sclRepeatEvent: + currentSelection = -1; + MainFormScroll(eventP->data.sclRepeat.newValue, eventP->data.sclRepeat.value, true); + break; + + case tblSelectEvent : + HandleSelectItem(eventP->data.tblSelect.row); + break; + + case keyDownEvent: + barP = GetObjectPtr(MainAppScrollBar); + SclGetScrollBar(barP, &valueP, &minP, &maxP, &pageSizeP); + + switch (eventP->data.keyDown.chr) + { + case vchrPageUp : + currentSelection = -1; + MainFormScrollLines(-pageSizeP, true); + handled = true; + break; + case vchrPageDown : + currentSelection = -1; + MainFormScrollLines(pageSizeP, true); + handled = true; + break; + case vchrPrevField : + HandlePrevKey(); + handled = true; + break; + case vchrNextField : + HandleNextKey(); + handled = true; + break; + case chrCarriageReturn : + if (currentSelection != -1) + HandleSelectItem(currentSelection); + handled = true; + break; + } + break; + + default: + break; + } + return(handled); +} + + diff --git a/handera-sdk-105/examples/ExampleH/Src/starter.c b/handera-sdk-105/examples/ExampleH/Src/starter.c new file mode 100644 index 0000000..f8561bd --- /dev/null +++ b/handera-sdk-105/examples/ExampleH/Src/starter.c @@ -0,0 +1,306 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project : Example H + * + *****************************************************************************/ + +#include +#include +#include "StarterRsc.h" + +#include "Vga.h" +#include "MainForm.h" + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ +typedef StarterAppInfoType* StarterAppInfoPtr; + +Boolean vgaPresent = false; + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_H' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ + + + /*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + /*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + /*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + + /*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + UInt32 version; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + +/*------------------------------------------------------------------------ + * Check to see if VGA extension present + *----------------------------------------------------------------------*/ + if (_TRGVGAFeaturePresent(&version)) + vgaPresent = true; + else + vgaPresent = false; + + return(errNone); +} + + /*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + + /*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + Err error; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + if ((error = AppStart()) != errNone) + return(error); + + if (vgaPresent) + VgaSetScreenMode(screenMode1To1, rotateModeNone); + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + + default: + break; + + } + return(errNone); +} + + + /*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} + diff --git a/handera-sdk-105/examples/ExampleH/StarterRsc.h b/handera-sdk-105/examples/ExampleH/StarterRsc.h new file mode 100644 index 0000000..fec216a --- /dev/null +++ b/handera-sdk-105/examples/ExampleH/StarterRsc.h @@ -0,0 +1,76 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 4:46:29 PM on Wednesday, April 04, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleH\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleH" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) +#define MainTextField 1001 //(Left Origin = 70, Top Origin = 146, Width = 60, Height = 12, Usable = 1, Editable = 1, Underline = 1, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 80, Font = Standard, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 0) +#define MainShiftGraffitiShift 1002 //(Left Origin = 140, Top Origin = 146) +#define MainAppLabel 1003 //(Left Origin = 4, Top Origin = 18, Usable = 1, Font = Bold) +#define MainAppTable 1005 //(Left Origin = 8, Top Origin = 30, Width = 141, Height = 110, Editable = 1, Rows = 20) +#define MainAppScrollBar 1006 //(Left Origin = 152, Top Origin = 29, Width = 7, Height = 112, Usable = 1, Value = 0, Minimum Value = 0, Maximum Value = 0, Page Size = 0) +#define MainAppGadget 1007 //(Left Origin = 4, Top Origin = 108, Width = 1, Height = 1, Usable = 1) +#define MainHelpButton 1008 //(Left Origin = 1, Top Origin = 146, Width = 36, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutText1Label 1103 //(Left Origin = 23, Top Origin = 61, Usable = 1, Font = Standard) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: Talt 1000 +#define LineNumberAlert 1000 +#define LineNumberOK 0 + +// Resource: MBAR 1000 +#define MainFormMenuBar 1000 + +// Resource: MENU 1000 +#define MainOptionsMenu 1000 +#define MainOptionsFont 1000 +#define MainOptionsAboutExampleH 1001 + +// Resource: tSTR 1000 +#define HelpString 1000 // "This is the help message for ExampleH." + +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: PICT 1400 +#define VGABigIconBitmap 1400 +// Resource: PICT 1500 +#define VGASmallIconBitmap 1500 +// Resource: PICT 1600 +#define VGABigIconInvertedBitmap 1600 +// Resource: taif 2002 +#define VGABigIconInvertedAppIconFamily 2002 + +// Resource: taif 2001 +#define VGASmallIconAppIconFamily 2001 + +// Resource: taif 2000 +#define VGABigIconAppIconFamily 2000 + +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 diff --git a/handera-sdk-105/examples/ExampleI/Memo.mcp b/handera-sdk-105/examples/ExampleI/Memo.mcp new file mode 100644 index 0000000..19bc1e6 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Memo.mcp differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/HandEra.r b/handera-sdk-105/examples/ExampleI/Rsc/HandEra.r new file mode 100644 index 0000000..bf63623 --- /dev/null +++ b/handera-sdk-105/examples/ExampleI/Rsc/HandEra.r @@ -0,0 +1,29 @@ +/*********************************************************************** + * + * Copyright (c) 1999-2001, TRG, All Rights Reserved + * + * PROJECT: HandEra 330 + * + * FILE: HandEra.r + * + * DESCRIPTION: + * + * AUTHOR: John Ehm + * + * DATE: 01/17/01 + * + **********************************************************************/ + + +type 'sKst' { + //Currently no data is stored in resource, need dummy otherwise + //resource is not linked in + unsigned longint; +}; + + +resource 'sKst' (1000, "HandEra Aware") +{ + 0x00000001; + +}; diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoApp.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoDelete.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/MemoPrefer.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoApp.rsrc new file mode 100644 index 0000000..0c43a76 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoApp.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoDelete.rsrc new file mode 100644 index 0000000..3f4e574 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoDelete.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoDetails.rsrc new file mode 100644 index 0000000..b0f00d1 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoDetails.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoEdit.rsrc new file mode 100644 index 0000000..1d7e22d Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoEdit.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoList.rsrc new file mode 100644 index 0000000..7537478 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoList.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoMisc.rsrc new file mode 100644 index 0000000..2e31232 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoMisc.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoPrefer.rsrc new file mode 100644 index 0000000..d05497b Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/deDE/Resource.Frk/MemoPrefer.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoApp.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoDelete.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/MemoPrefer.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoApp.rsrc new file mode 100644 index 0000000..556c548 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoApp.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoDelete.rsrc new file mode 100644 index 0000000..48c6116 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoDelete.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoDetails.rsrc new file mode 100644 index 0000000..36cae70 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoDetails.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoEdit.rsrc new file mode 100644 index 0000000..2e56dd1 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoEdit.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoList.rsrc new file mode 100644 index 0000000..6e17cc0 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoList.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoMisc.rsrc new file mode 100644 index 0000000..1a48852 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoMisc.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoPrefer.rsrc new file mode 100644 index 0000000..5211c04 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/esES/Resource.Frk/MemoPrefer.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoApp.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoDelete.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/MemoPrefer.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoApp.rsrc new file mode 100644 index 0000000..d590c10 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoApp.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoDelete.rsrc new file mode 100644 index 0000000..5298a79 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoDelete.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoDetails.rsrc new file mode 100644 index 0000000..9d3d926 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoDetails.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoEdit.rsrc new file mode 100644 index 0000000..cb2b78e Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoEdit.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoList.rsrc new file mode 100644 index 0000000..9ff4029 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoList.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoMisc.rsrc new file mode 100644 index 0000000..d83a9ac Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoMisc.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoPrefer.rsrc new file mode 100644 index 0000000..322b269 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/frFR/Resource.Frk/MemoPrefer.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoApp.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoDelete.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/MemoPrefer.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoApp.rsrc new file mode 100644 index 0000000..10a9b8b Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoApp.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoDelete.rsrc new file mode 100644 index 0000000..295f2ac Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoDelete.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoDetails.rsrc new file mode 100644 index 0000000..544ebf7 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoDetails.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoEdit.rsrc new file mode 100644 index 0000000..f0bac0f Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoEdit.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoList.rsrc new file mode 100644 index 0000000..1dd0ef6 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoList.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoMisc.rsrc new file mode 100644 index 0000000..a6bc427 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoMisc.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoPrefer.rsrc new file mode 100644 index 0000000..026c711 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/itIT/Resource.Frk/MemoPrefer.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoApp.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoDelete.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/MemoPrefer.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoApp.rsrc new file mode 100644 index 0000000..83e59a4 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoApp.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoDelete.rsrc new file mode 100644 index 0000000..355f959 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoDelete.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoDetails.rsrc new file mode 100644 index 0000000..c01d429 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoDetails.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoEdit.rsrc new file mode 100644 index 0000000..42018ca Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoEdit.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoList.rsrc new file mode 100644 index 0000000..bf36c04 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoList.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoMisc.rsrc new file mode 100644 index 0000000..7c3e1a0 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoMisc.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoPrefer.rsrc new file mode 100644 index 0000000..7874e09 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Localized/jpJP/Resource.Frk/MemoPrefer.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/MemoApp.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/MemoDelete.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/MemoDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/MemoEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/MemoList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/MemoMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/MemoPrefer.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoApp.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoApp.rsrc new file mode 100644 index 0000000..956aaa7 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoApp.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoDelete.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoDelete.rsrc new file mode 100644 index 0000000..cabd747 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoDelete.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoDetails.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoDetails.rsrc new file mode 100644 index 0000000..ac7205e Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoDetails.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoEdit.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoEdit.rsrc new file mode 100644 index 0000000..898c937 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoEdit.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoList.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoList.rsrc new file mode 100644 index 0000000..7107b11 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoList.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoMisc.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoMisc.rsrc new file mode 100644 index 0000000..2c08946 Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoMisc.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoPrefer.rsrc b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoPrefer.rsrc new file mode 100644 index 0000000..94bf3bf Binary files /dev/null and b/handera-sdk-105/examples/ExampleI/Rsc/Resource.Frk/MemoPrefer.rsrc differ diff --git a/handera-sdk-105/examples/ExampleI/Src/MemoDB.c b/handera-sdk-105/examples/ExampleI/Src/MemoDB.c new file mode 100644 index 0000000..fce2e72 --- /dev/null +++ b/handera-sdk-105/examples/ExampleI/Src/MemoDB.c @@ -0,0 +1,532 @@ +/****************************************************************************** + * + * Copyright (c) 1995-2000 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MemoDB.c + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * Memo Manager routines + * + * History: + * 1/3/95 rsf - Created + * 9/13/95 mlb - added MemoNewRecord for use by mbs shell command + * 10/02/99 jmp - Add MemoGetDatabase() routine. + * + *****************************************************************************/ + +#include + +#include + +#include "MemoDB.h" +#include "MemoMain.h" + + +/************************************************************ + * + * FUNCTION: MemoLocalizeAppInfo + * + * DESCRIPTION: Look for localize app info strings and copy + * them into the app info block. + * + * PARAMETERS: application info ptr + * + * RETURNS: nothing + * + * CREATED: 12/13/95 + * + * BY: Roger Flores + * + *************************************************************/ +static void MemoLocalizeAppInfo (MemoAppInfoPtr appInfoP) +{ + Int16 i; + Char ** stringsP; + MemHandle stringsH; + MemHandle localizedAppInfoH; + Char * localizedAppInfoP; + MemoAppInfoPtr nilP = 0; + + + localizedAppInfoH = DmGetResource(appInfoStringsRsc, LocalizedAppInfoStr); + if (localizedAppInfoH) + { + localizedAppInfoP = MemHandleLock(localizedAppInfoH); + stringsH = SysFormPointerArrayToStrings(localizedAppInfoP, + dmRecNumCategories); + stringsP = MemHandleLock(stringsH); + + // Copy each category + for (i = 0; i < dmRecNumCategories; i++) + { + if (stringsP[i][0] != '\0') + DmStrCopy(appInfoP, (UInt32) nilP->categoryLabels[i], stringsP[i]); + } + + MemPtrFree(stringsP); + MemPtrUnlock(localizedAppInfoP); + } +} + + +/************************************************************ + * + * FUNCTION: MemoAppInfoInit + * + * DESCRIPTION: Create an app info chunk if missing. Set + * the strings to a default. + * + * PARAMETERS: database pointer + * + * RETURNS: 0 if successful, errorcode if not + * + * CREATED: 1/3/95 + * + * BY: Roger Flores + * + *************************************************************/ +Err MemoAppInfoInit(DmOpenRef dbP) +{ + UInt16 cardNo; + MemHandle h; + LocalID dbID; + LocalID appInfoID; + MemoAppInfoPtr nilP = 0; + MemoAppInfoPtr appInfoP; + + if (DmOpenDatabaseInfo(dbP, &dbID, NULL, NULL, &cardNo, NULL)) + return dmErrInvalidParam; + if (DmDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, &appInfoID, NULL, NULL, NULL)) + return dmErrInvalidParam; + + if (appInfoID == 0) + { + h = DmNewHandle (dbP, sizeof (MemoAppInfoType)); + if (! h) return dmErrMemError; + + appInfoID = MemHandleToLocalID (h); + DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &appInfoID, NULL, NULL, NULL); + } + + appInfoP = MemLocalIDToLockedPtr(appInfoID, cardNo); + + // Clear the app info block. + DmSet (appInfoP, 0, sizeof(MemoAppInfoType), 0); + + // Initialize the categories. + CategoryInitialize ((AppInfoPtr) appInfoP, LocalizedAppInfoStr); + + // Initialize the sort order. + DmSet (appInfoP, (UInt32)&nilP->sortOrder, sizeof(appInfoP->sortOrder), + soAlphabetic); + + MemPtrUnlock(appInfoP); + + // The conduit ignores dmHdrAttrAppInfoDirty + return 0; +} + + +/************************************************************ + * + * FUNCTION: MemoGetAppInfo + * + * DESCRIPTION: Get the app info chunk + * + * PARAMETERS: database pointer + * + * RETURNS: MemHandle to the to do application info block + * (MemoAppInfoType) + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/18/96 Initial Revision + * + *************************************************************/ +static MemHandle MemoGetAppInfo (DmOpenRef dbP) +{ + Err error; + UInt16 cardNo; + LocalID dbID; + LocalID appInfoID; + + error = DmOpenDatabaseInfo (dbP, &dbID, NULL, NULL, &cardNo, NULL); + ErrFatalDisplayIf (error, "Get getting app info block"); + + error = DmDatabaseInfo (cardNo, dbID, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, &appInfoID, NULL, NULL, NULL); + ErrFatalDisplayIf (error, "Get getting app info block"); + + return ((MemHandle) MemLocalIDToGlobal (appInfoID, cardNo)); +} + + +/************************************************************ + * + * FUNCTION: MemoCompareRecords + * + * DESCRIPTION: Compare two records. + * + * PARAMETERS: database record 1 + * database record 2 + * + * RETURNS: -n if record one is less (n != 0) + * n if record two is less + * + * COMMENTS: Compare the two records key by key until + * there is a difference. Return -n if r1 is less or n if r2 + * is less. A zero is never returned because if two records + * seem identical then their unique IDs are compared! + * + * This function accepts record data chunk pointers to avoid + * requiring that the record be within the database. This is + * important when adding records to a database. This prevents + * determining if a record is a deleted record (which are kept + * at the end of the database and should be considered "greater"). + * The caller should test for deleted records before calling this + * function! + * + * HISTORY: + * 07/18/96 art Created by Art Lamb. + * 11/30/00 kwk Use TxtCompare vs. StrCompare to avoid one + * extra trap call. + * + *************************************************************/ +static Int16 MemoCompareRecords (MemoDBRecordPtr r1, + MemoDBRecordPtr r2, Int16 sortOrder, SortRecordInfoPtr UNUSED_PARAM(info1), + SortRecordInfoPtr UNUSED_PARAM(info2), MemHandle UNUSED_PARAM(appInfoH)) +{ + Int16 result; + + // Alphabetize; + if (sortOrder == soAlphabetic) + { + result = TxtCompare( &r1->note, // const Char *s1 + 0xFFFF, // UInt16 s1Len, + NULL, // UInt16 *s1MatchLen, + &r2->note, // const Char *s2, + 0xFFFF, // UInt16 s2Len, + NULL); // UInt16 *s2MatchLen + } + else + result = 0; + + return result; +} + + +/************************************************************ + * + * FUNCTION: MemoGetSortOrder + * + * DESCRIPTION: This routine get the sort order value from the + * to do application info block. + * + * PARAMETERS: database pointer + * + * RETURNS: true - if the to do record are sorted by priority, + * false - if the records are sorted by due date. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/18/96 Initial Revision + * + *************************************************************/ +UInt8 MemoGetSortOrder (DmOpenRef dbP) +{ + UInt8 sortOrder; + MemoAppInfoPtr appInfoP; + + appInfoP = MemHandleLock (MemoGetAppInfo (dbP)); + sortOrder = appInfoP->sortOrder; + MemPtrUnlock (appInfoP); + + return (sortOrder); +} + + +/************************************************************ + * + * FUNCTION: MemoChangeSortOrder + * + * DESCRIPTION: Change the Memo Database's sort order + * + * PARAMETERS: database pointer + * TRUE if sort by company + * + * RETURNS: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/18/96 Initial Revision + * + *************************************************************/ +Err MemoChangeSortOrder(DmOpenRef dbP, Boolean sortOrder) +{ + MemoAppInfoPtr appInfoP; + MemoAppInfoPtr nilP = 0; + + + appInfoP = MemHandleLock (MemoGetAppInfo (dbP)); + + if (appInfoP->sortOrder != sortOrder) + { + DmWrite (appInfoP, (UInt32)&nilP->sortOrder, &sortOrder, sizeof(appInfoP->sortOrder)); + + if (sortOrder == soAlphabetic) + DmInsertionSort (dbP, (DmComparF *) &MemoCompareRecords, (Int16) sortOrder); + } + + MemPtrUnlock (appInfoP); + + return 0; +} + + +/************************************************************ + * + * FUNCTION: MemoSort + * + * DESCRIPTION: Sort the appointment database. + * + * PARAMETERS: database record + * + * RETURNS: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/18/96 Initial Revision + * gap 6/29/00 When in manual sort mode this + * routine was exiting immediately which caused + * deleted and non-deleted records to be mixed in + * the database as opposed to having deleted records + * all appended at the end of the database. Now check + * to move records above all deleted records (which can + * occur in the case of receiving multiple beamed records). + * + *************************************************************/ +void MemoSort (DmOpenRef dbP) +{ + Int16 sortOrder; + + sortOrder = MemoGetSortOrder (dbP); + DmInsertionSort (dbP, (DmComparF *) &MemoCompareRecords, (Int16) sortOrder); +} + + +/************************************************************ + * + * FUNCTION: MemoNewRecord + * + * DESCRIPTION: Create a new record + * + * PARAMETERS: database pointer + * database record + * + * RETURNS: zero if successful, errorcode if not + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * monty 9/13/95 Initial Revision + * + *************************************************************/ +Err MemoNewRecord (DmOpenRef dbP, MemoItemPtr item, UInt16 *index) +{ + Err result; + int size = 0; + UInt32 offset; + MemHandle recordH; + MemoDBRecordPtr recordP, nilP=0; + + // Compute the size of the new memo record. + size = StrLen (item->note); + + // Allocate a chunk in the database for the new record. + recordH = (MemHandle)DmNewHandle(dbP, (UInt32) size); + if (recordH == NULL) + return dmErrMemError; + + // Pack the the data into the new record. + recordP = MemHandleLock (recordH); + offset = (UInt32)&nilP->note; + DmStrCopy(recordP, offset, item->note); + + MemPtrUnlock (recordP); + + // Insert the record. + result = DmAttachRecord(dbP, index, recordH, 0); + if (result) + MemHandleFree(recordH); + + return result; +} + + +/************************************************************ + * + * FUNCTION: MemoSortRecord + * + * DESCRIPTION: Move the passed record to its correct sort + * position. + * + * PARAMETERS: database pointer + * record index + * + * RETURNS: zero if successful, errorcode if not + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/18/96 Initial Revision + * gap 6/29/00 When user is in manual sort mode, the sort + * routine was exiting immediately which caused + * deleted and non-deleted records to be mixed in + * the database as opposed to having deleted records + * all appended at the end of the database. Now check + * to move record above all deleted records (in the case + * of new records) before exiting the routine when + * manual sort is selected. + * + * + *************************************************************/ +Err MemoSortRecord (DmOpenRef dbP, UInt16 * indexP) +{ + Err err; + Int16 sortOrder; + UInt16 index; + UInt16 attributes; + UInt32 uniqueID; + MemHandle recordH; + MemHandle h; + Boolean dontMove; + MemoDBRecordPtr cmp; + MemoDBRecordPtr recordP; + + sortOrder = MemoGetSortOrder (dbP); + + // Check if the record is already in the correct position. + recordP = MemHandleLock (DmQueryRecord (dbP, *indexP)); + if (*indexP > 0) + { + // This record wasn't deleted and deleted records are at the end of the + // database so the prior record may not be deleted! + h = DmQueryRecord (dbP, *indexP-1); + if (! h) + dontMove = false; + else + { + if (sortOrder == soUnsorted) + dontMove = true; + else + { + cmp = MemHandleLock (h); + dontMove = (MemoCompareRecords (cmp, recordP, sortOrder, NULL, NULL, 0) < 1); + MemPtrUnlock (cmp); + } + } + } + else + dontMove = true; + + if (dontMove && (*indexP+1 < DmNumRecords (dbP))) + { + DmRecordInfo(dbP, *indexP+1, &attributes, NULL, NULL); + if ( ! (attributes & dmRecAttrDelete) ) + { + cmp = MemHandleLock (DmQueryRecord (dbP, *indexP+1)); + dontMove &= (MemoCompareRecords (recordP, cmp, sortOrder, NULL, NULL, 0) < 1); + MemPtrUnlock (cmp); + } + } + MemPtrUnlock (recordP); + + if (dontMove) return (0); + + + // Since the routine that determines the records sort position uses a + // binary search algorythm we need to remove the record from the database + // before we can determine its new position. We will also save and restore the + // record's attributes and unique ID. + DmRecordInfo (dbP, *indexP, &attributes, &uniqueID, NULL); + + err = DmDetachRecord (dbP, *indexP, &recordH); + if (err) return (err); + + recordP = MemHandleLock (recordH); + index = DmFindSortPosition (dbP, recordP, NULL, (DmComparF *)MemoCompareRecords, sortOrder); + MemPtrUnlock (recordP); + + err = DmAttachRecord (dbP, &index, recordH, 0); + if (err) return (err); + + DmSetRecordInfo (dbP, index, &attributes, &uniqueID); + + *indexP = index; + + return (err); +} + +/*********************************************************************** + * + * FUNCTION: MemoGetDatabase + * + * DESCRIPTION: Get the application's database. Open the database if it + * exists, create it if neccessary. + * + * PARAMETERS: *dbPP - pointer to a database ref (DmOpenRef) to be set + * mode - how to open the database (dmModeReadWrite) + * + * RETURNED: Err - zero if no error, else the error + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * jmp 10/02/99 Initial Revision + * + ***********************************************************************/ +Err MemoGetDatabase (DmOpenRef *dbPP, UInt16 mode) +{ + Err error = 0; + DmOpenRef dbP; + UInt16 cardNo; + LocalID dbID; + + *dbPP = NULL; + + // Find the application's data file. If it doesn't exist create it. + dbP = DmOpenDatabaseByTypeCreator (memoDBType, sysFileCMemo, mode); + if (!dbP) + { + error = DmCreateDatabase (0, memoDBName, sysFileCMemo, memoDBType, false); + if (error) + return error; + + dbP = DmOpenDatabaseByTypeCreator(memoDBType, sysFileCMemo, mode); + if (!dbP) + return (1); + + // Set the backup bit. This is to aid syncs with non Palm software. + SetDBBackupBit(dbP); + + error = MemoAppInfoInit (dbP); + if (error) + { + DmOpenDatabaseInfo(dbP, &dbID, NULL, NULL, &cardNo, NULL); + DmCloseDatabase(dbP); + DmDeleteDatabase(cardNo, dbID); + return error; + } + } + + *dbPP = dbP; + return 0; +} diff --git a/handera-sdk-105/examples/ExampleI/Src/MemoDB.h b/handera-sdk-105/examples/ExampleI/Src/MemoDB.h new file mode 100644 index 0000000..3119b3c --- /dev/null +++ b/handera-sdk-105/examples/ExampleI/Src/MemoDB.h @@ -0,0 +1,87 @@ +/****************************************************************************** + * + * Copyright (c) 1995-1999 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MemoDB.h + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * Header for the Memo Manager + * + * History: + * 1/3/95 rsf - Created + * 9/13/95 mlb - added memo item type and MemoNewRecord + * 10/02/99 jmp - Added MemoGetDatabase() prototype. + * + *****************************************************************************/ + +#ifndef __MEMODB_H__ +#define __MEMODB_H__ + +#define LocalizedAppInfoStr 1000 + +typedef struct { + UInt16 renamedCategories; // bitfield of categories with a different name + char categoryLabels[dmRecNumCategories][dmCategoryLength]; + UInt8 categoryUniqIDs[dmRecNumCategories]; + UInt8 lastUniqID; // Uniq IDs generated by the device are between + // 0 - 127. Those from the PC are 128 - 255. + UInt8 reserved1; // from the compiler word aligning things + UInt16 reserved2; + UInt16 reserved3; + UInt8 sortOrder; + UInt8 reserved; +} MemoAppInfoType; + +typedef MemoAppInfoType * MemoAppInfoPtr; + + +// Sort orders +#define soUnsorted 0 +#define soAlphabetic 1 + + +typedef struct { + char note; // null terminated + UInt8 reserved; +} MemoDBRecordType; + +typedef MemoDBRecordType * MemoDBRecordPtr; + +typedef struct { + Char * note; +} MemoItemType; + +typedef MemoItemType * MemoItemPtr; + + +#ifdef __cplusplus +extern "C" { +#endif + + +//------------------------------------------------------------------- +// Routines +//------------------------------------------------------------------- +extern Err MemoAppInfoInit(DmOpenRef dbP); + +extern Err MemoNewRecord(DmOpenRef dbP, MemoItemPtr item, UInt16 *index); + +extern Err MemoChangeSortOrder(DmOpenRef dbP, UInt8 sortOrder); + +extern UInt8 MemoGetSortOrder (DmOpenRef dbP); + +extern void MemoSort (DmOpenRef dbP); + +extern Err MemoSortRecord (DmOpenRef dbP, UInt16 * indexP); + +extern Err MemoGetDatabase (DmOpenRef *dbPP, UInt16 mode); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/handera-sdk-105/examples/ExampleI/Src/MemoMain.c b/handera-sdk-105/examples/ExampleI/Src/MemoMain.c new file mode 100644 index 0000000..f00d083 --- /dev/null +++ b/handera-sdk-105/examples/ExampleI/Src/MemoMain.c @@ -0,0 +1,4994 @@ +/****************************************************************************** + * + * Copyright (c) 1995-2000 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MemoMain.c + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This is the Memo application's main module. This module + * starts the application, dispatches events, and stops + * the application. + * + * History: + * Feb 21, 1995 Created by Art Lamb + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "MemoDB.h" +#include "MemoRsc.h" +#include "MemoMain.h" + +/* TRG */ +#include "Vga.h" +/* end TRG */ + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define memoVersionNum 3 +#define memoPrefsVersionNum 3 +#define memoPrefID 0x00 + + +#define newMemoSize 64 + +#define noRecordSelected 0xffff +#define noRecordSelectedID -1 + +// Update codes, used to determine how the to do list view should +// be redrawn. +#define updateRedrawAll 0x00 +#define updateCategoryChanged 0x01 +#define updateDisplayOptsChanged 0x02 +#define updateFontChanged 0x04 + + +//The listViewIndexStringSize is the size of the character array +//that holds the string representation of the index that is displayed to +//the left of the memo title in the list view. The string can have a +//range of 1 - 99,999 with the current value. +#define listViewIndexStringSize 7 + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ + +typedef struct { + UInt16 topVisibleRecord; + UInt16 currentRecord; + UInt16 currentView; + UInt16 currentCategory; + FontID v20editFont; + UInt8 reserved1; + UInt16 editScrollPosition; + Boolean showAllCategories; + UInt8 reserved2; + UInt32 currentRecordID; + Boolean saveBackup; + + // Version 2 preferences + FontID v20listFont; + + // Version 3 preferences + FontID editFont; + FontID listFont; +} MemoPreferenceType; + +typedef struct { + DmOpenRef db; + Char * categoryName; + UInt16 categoryIndex; +} AcceptBeamType; + + + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + +static DmOpenRef MemoDB; +static char CategoryName [dmCategoryLength]; +static UInt16 MemosInCategory; +static privateRecordViewEnum PrivateRecordVisualStatus; +static MenuBarPtr CurrentMenu; + +/* TRG */ +static Boolean vgaExists = false; // larger screen support +static Int16 selectedItem = -1; // one hand operation +/* end TRG */ +// The following global variable are saved to a state file. +static UInt16 TopVisibleRecord = 0; +static UInt16 CurrentRecord = noRecordSelected; +static UInt16 CurrentView = ListView; +static UInt16 CurrentCategory = dmAllCategories; +static Boolean ShowAllCategories = true; +static FontID ListFont = stdFont; +static FontID EditFont = stdFont; +static UInt16 EditScrollPosition = 0; +static Boolean SaveBackup = true; + +static Boolean InPhoneLookup = false; + +static UInt16 TopRowPositionInCategory; + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ +static Boolean EditViewDeleteRecord (void); +static void MemoLoadPrefs(UInt32* currentRecordID); +static void MemoSavePrefs(UInt16 scrollPosition); +static void ListViewDisplayMask (RectanglePtr bounds); +static Boolean ListViewUpdateDisplay (UInt16 updateCode); +static void RegisterLocaleChangingNotification(void); + +/* TRG */ +static void ListViewResizeForm(FormPtr frmP, Boolean draw); +static void EditViewResizeForm(FormPtr frmP, Boolean draw); +static void ListViewSelectTableItem (Boolean selected, TablePtr table, Int16 row, Int16 column, RectangleType *r); +/* end TRG */ +/*********************************************************************** + * + * FUNCTION: SetDBBackupBit + * + * DESCRIPTION: This routine sets the backup bit on the given database. + * This is to aid syncs with non Palm software. + * If no DB is given, open the app's default database and set + * the backup bit on it. + * + * PARAMETERS: dbP - the database to set backup bit, + * can be NULL to indicate app's default database + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * grant 4/1/99 Initial Revision + * + ***********************************************************************/ +void SetDBBackupBit(DmOpenRef dbP) +{ + DmOpenRef localDBP; + LocalID dbID; + UInt16 cardNo; + UInt16 attributes; + + // Open database if necessary. If it doesn't exist, simply exit (don't create it). + if (dbP == NULL) + { + localDBP = DmOpenDatabaseByTypeCreator (memoDBType, sysFileCMemo, dmModeReadWrite); + if (localDBP == NULL) return; + } + else + { + localDBP = dbP; + } + + // now set the backup bit on localDBP + DmOpenDatabaseInfo(localDBP, &dbID, NULL, NULL, &cardNo, NULL); + DmDatabaseInfo(cardNo, dbID, NULL, &attributes, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); + attributes |= dmHdrAttrBackup; + DmSetDatabaseInfo(cardNo, dbID, NULL, &attributes, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); + + // close database if necessary + if (dbP == NULL) + { + DmCloseDatabase(localDBP); + } +} + +/*********************************************************************** + * + * FUNCTION: CreateDefaultDatabase + * + * DESCRIPTION: This routine creates the default database from the + * saved image in a resource in the application. + * + * PARAMETERS: none + * + * RETURNED: 0 - if no error + * otherwise appropriate error value + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * vivek 8/17/00 Initial Revision + * + ***********************************************************************/ +static Err CreateDefaultDatabase(void) +{ + MemHandle resH; + DmOpenRef dbP; + Err error = errNone; + + // Attempt to get our default data image and create our + // database. + resH = DmGet1Resource(sysResTDefaultDB, sysResIDDefaultDB); + if (resH) + { + error = DmCreateDatabaseFromImage(MemHandleLock(resH)); + + if (!error) + { + MemHandleUnlock(resH); + DmReleaseResource(resH); + + // Set the bakcup bit on the newly created DB. + SetDBBackupBit(NULL); + } + } + + // If there is no default data, or we had a problem creating it, + // then attempt to create an empty database. + if (!resH || error) + { + error = MemoGetDatabase (&dbP, dmModeReadWrite); + + if (!error) + DmCloseDatabase(dbP); + + } + return error; +} + +/* TRG */ +/*********************************************************************** + * + * FUNCTION: ToolsVgaModeSupported + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + * REVISION HISTORY: + * + ***********************************************************************/ +static Boolean ToolsVgaModeSupported(void) +{ + VgaScreenModeType mode; + VgaRotateModeType rotate; + + if (vgaExists) + { + VgaGetScreenMode(&mode, &rotate); + + return (mode == screenMode1To1); + } + + return false; +} +/* end TRG */ + +/*********************************************************************** + * + * FUNCTION: StartApplication + * + * DESCRIPTION: This routine opens the application's database, loads the + * saved-state information and initializes global variables. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * grant 4/6/99 Moved code to set backup bit into SetDBBackupBit + * jmp 10/2/99 Call new MemoGetDataBase() to create database + * if it doesn't already exist. + * + ***********************************************************************/ +static UInt16 StartApplication (void) +{ + Err err = 0; + UInt16 attr; + UInt16 mode; + UInt32 uniqueID; + UInt32 currentRecordID = 0; + Boolean recordFound = false; + UInt32 vgaVersion; + +/* TRG */ + if (_TRGVGAFeaturePresent(&vgaVersion)) + { + VgaRotateModeType rotate; + vgaExists = true; + + VgaGetScreenMode(NULL, &rotate); + VgaSetScreenMode(screenMode1To1, rotate); + } + else + vgaExists = false; +/* end TRG */ + + // Determime if secert record should be shown. + PrivateRecordVisualStatus = (privateRecordViewEnum)PrefGetPreference (prefShowPrivateRecords); + if (PrivateRecordVisualStatus == hidePrivateRecords) + { + mode = dmModeReadWrite; + } + else + { + mode = dmModeReadWrite | dmModeShowSecret; + } + + // Find the application's data file. If it doesn't exist, create it. + err = MemoGetDatabase (&MemoDB, mode); + if (err) + return err; + + // Read the preferences. + MemoLoadPrefs(¤tRecordID); + + // The file may have been synchronized since the last time we used it, + // check that the current record and the currrent category still + // exist. Also, if secret records are being hidden, check if the + // the current record is marked secret. + CategoryGetName (MemoDB, CurrentCategory, CategoryName); + if (*CategoryName == 0) + { + CurrentCategory = dmAllCategories; + ShowAllCategories = true; + } + + if ( DmQueryRecord (MemoDB, CurrentRecord) != 0) + { + DmRecordInfo (MemoDB, CurrentRecord, &attr, &uniqueID, NULL); + recordFound = (uniqueID == currentRecordID) && + ((PrivateRecordVisualStatus == showPrivateRecords) || + (!(attr & dmRecAttrSecret))); + } + + if (! recordFound) + { + TopVisibleRecord = 0; + CurrentRecord = noRecordSelected; + CurrentView = ListView; + EditScrollPosition = 0; + } + + if (ShowAllCategories) + MemosInCategory = DmNumRecordsInCategory (MemoDB, dmAllCategories); + else + MemosInCategory = DmNumRecordsInCategory (MemoDB, CurrentCategory); + + return (err); +} + + +/*********************************************************************** + * + * FUNCTION: StopApplication + * + * DESCRIPTION: This routine closes the application's database + * and saves the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * + ***********************************************************************/ +static void StopApplication (void) +{ + UInt16 scrollPosition = 0; + FormPtr frm; + FieldPtr fld; + + + // If we are in the "edit view", get the current scroll position. + if ((CurrentView == EditView) && (CurrentRecord != noRecordSelected)) + { + frm = FrmGetFormPtr (EditView); + fld = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, EditMemoField)); + scrollPosition = FldGetScrollPosition (fld); + } + + // Close all open forms, this will force any unsaved data to + // be written to the database. + FrmCloseAllForms (); + + // Write the preferences / saved-state information. + MemoSavePrefs(scrollPosition); + + // Close the application's data file. + DmCloseDatabase (MemoDB); +} + + +/*********************************************************************** + * + * FUNCTION: SyncNotification + * + * DESCRIPTION: This routine is an entry point of the memo application. + * It is called when the application's database is + * synchronized. This routine will resort the database. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 10/17/96 Initial Revision + * jmp 10/02/99 Changed call to DmOpenDatabaseByTypeCreator() to + * MemoGetDatabase(). + * + ***********************************************************************/ +static void SyncNotification (void) +{ + DmOpenRef dbP; + Err err; + + // Find the application's data file. + err = MemoGetDatabase(&dbP, dmModeReadWrite); + if (err) + return; + + // Resort the database. + MemoSort (dbP); + + DmCloseDatabase (dbP); +} + + +/*********************************************************************** + * + * FUNCTION: RegisterLocaleChangingNotification + + * + * DESCRIPTION: Register for NotifyMgr notifications for locale chagning. + * DOLATER : This function and the one above can be rolled into one. + * + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * vivek 8/01/00 Initial Revision + * + ***********************************************************************/ +void RegisterLocaleChangingNotification(void) +{ + UInt16 cardNo; + LocalID dbID; + Err err; + + err = SysCurAppDatabase(&cardNo, &dbID); + ErrNonFatalDisplayIf(err != errNone, "can't get app db info"); + if(err == errNone) + { + err = SysNotifyRegister(cardNo, dbID, sysNotifyLocaleChangedEvent, + NULL, sysNotifyNormalPriority, NULL); + +#if EMULATION_LEVEL == EMULATION_NONE + ErrNonFatalDisplayIf((err != errNone) && (err != sysNotifyErrDuplicateEntry), "can't register"); +#endif + + } + + return; +} + +/*********************************************************************** + * + * FUNCTION: RegisterData + * + * DESCRIPTION: Register with the Exchange Manager to receive .txt and + * text/plain. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + * HISTORY: + * 7/28/00 dje Initial Revision. + * + ***********************************************************************/ +static void RegisterData(void) +{ + MemHandle resH; + void *desc; + + resH = DmGetResource(strRsc, ExgDescriptionStr); + desc = MemHandleLock(resH); + + ExgRegisterDatatype(sysFileCMemo, exgRegExtensionID, memoExtension, desc, 0); + ExgRegisterDatatype(sysFileCMemo, exgRegTypeID, memoMIMEType, desc, 0); + + MemHandleUnlock(resH); + DmReleaseResource(resH); +} + + +/*********************************************************************** + * + * FUNCTION: MemoLoadPrefs + * + * DESCRIPTION: Load the preferences and do any fixups needed for backwards + * and forwards compatibility + * + * PARAMETERS: currentRecordID <- returned record id from preferences. + * + * RETURNED: nothing + * + * HISTORY: + * 01/13/98 BGT Initial Revision. + * 08/04/99 kwk Cleaned up setting EditFont/ListFont from prefs. + * + ***********************************************************************/ +void MemoLoadPrefs(UInt32* currentRecordID) +{ + MemoPreferenceType prefs; + UInt16 prefsSize; + Int16 prefsVersion; + Boolean needFontInfo = false; + + // Read the preferences / saved-state information. + prefsSize = sizeof (MemoPreferenceType); + prefsVersion = PrefGetAppPreferences (sysFileCMemo, memoPrefID, &prefs, &prefsSize, true); + if (prefsVersion > memoPrefsVersionNum) { + prefsVersion = noPreferenceFound; + } + + if (prefsVersion > noPreferenceFound) + { + // Try to carry forward the version 2 preferences for the font + if (prefsVersion < 2) + { + // No font data in original prefs + needFontInfo = true; + } + else if (prefsVersion == 2) + { + prefs.editFont = prefs.v20editFont; + prefs.listFont = prefs.v20listFont; + + // Use the 'better' large font if we've got it, since version 2 + // prefs would have been created on an older version of the OS + // which didn't have the largeBoldFont available. + if (prefs.editFont == largeFont) + prefs.editFont = largeBoldFont; + + if (prefs.listFont == largeFont) + prefs.listFont = largeBoldFont; + } + + TopVisibleRecord = prefs.topVisibleRecord; + CurrentRecord = prefs.currentRecord; + CurrentView = prefs.currentView; + CurrentCategory = prefs.currentCategory; + EditScrollPosition = prefs.editScrollPosition; + ShowAllCategories = prefs.showAllCategories; + SaveBackup = prefs.saveBackup; + *currentRecordID = prefs.currentRecordID; + } + else + { + needFontInfo = true; + } + + // If the prefs didn't supply us with font info, we'll need to get it ourselves. + if (needFontInfo) + { + UInt32 defaultFont; + FtrGet(sysFtrCreator, sysFtrDefaultFont, &defaultFont); +/* TRG */ + /* the default font feature is for 160x160 apps, + we need to convert to Vga font. */ + if (vgaExists) + defaultFont = VgaBaseToVgaFont(defaultFont); +/* end TRG */ + EditFont = (FontID)defaultFont; + ListFont = (FontID)defaultFont; + } + else + { + EditFont = prefs.editFont; + ListFont = prefs.listFont; + } + + // The first time this app starts register to handle .txt and text/plain. + if (prefsVersion != memoPrefsVersionNum) + RegisterData(); +} + + +/*********************************************************************** + * + * FUNCTION: MemoSavePrefs + * + * DESCRIPTION: Save the preferences and do any fixups needed for backwards + * and forwards compatibility + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * BGT 1/13/98 Initial Revision + * + ***********************************************************************/ +void MemoSavePrefs(UInt16 scrollPosition) +{ + MemoPreferenceType prefs; + UInt32 uniqueID; + + // Write the preferences / saved-state information. + prefs.topVisibleRecord = TopVisibleRecord; + prefs.currentRecord = CurrentRecord; + prefs.currentView = CurrentView; + prefs.currentCategory = CurrentCategory; + prefs.showAllCategories = ShowAllCategories; + prefs.editScrollPosition = scrollPosition; + prefs.saveBackup = SaveBackup; + prefs.editFont = EditFont; + prefs.listFont = ListFont; + + prefs.v20editFont = stdFont; + prefs.v20listFont = stdFont; + + // Clear reserved fields so prefs don't look "different" just from stack garbage! + prefs.reserved1 = 0; + prefs.reserved2 = 0; + + // Get the current record's unique id and save it with the state + // information. + if ( DmQueryRecord (MemoDB, CurrentRecord) != 0) + { + DmRecordInfo (MemoDB, CurrentRecord, NULL, &uniqueID, NULL); + prefs.currentRecordID = uniqueID; + } + else + prefs.currentRecordID = noRecordSelectedID; + + // Write the state information. + PrefSetAppPreferences (sysFileCMemo, memoPrefID, memoPrefsVersionNum, &prefs, + sizeof (MemoPreferenceType), true); + + +} + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * + ***********************************************************************/ +static void * GetObjectPtr (UInt16 objectID) +{ + FormPtr frm; + + frm = FrmGetActiveForm (); + return (FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, objectID))); + +} + +/*********************************************************************** + * + * FUNCTION: GetFocusObjectPtr + * + * DESCRIPTION: This routine returns a pointer to the field object, in + * the current form, that has the focus. + * + * PARAMETERS: nothing + * + * RETURNED: pointer to a field object or NULL of there is no fucus + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * + ***********************************************************************/ +static FieldPtr GetFocusObjectPtr (void) +{ + FormPtr frm; + UInt16 focus; + + frm = FrmGetActiveForm (); + focus = FrmGetFocus (frm); + if (focus == noFocus) + return (NULL); + + return (FrmGetObjectPtr (frm, focus)); +} + + +/*********************************************************************** + * + * FUNCTION: SeekRecord + * + * DESCRIPTION: Given the index of a 'to do' record, this routine scans + * forwards or backwards for displayable 'to do' records. + * + * PARAMETERS: indexP - pointer to the index of a record to start from; + * the index of the record sought is returned in + * this parameter. + * + * offset - number of records to skip: + * 0 - mean seek from the current record to the + * next display record, if the current record is + * a displayable record, its index is retuned. + * 1 - mean seek foreward, skipping one displayable + * record + * -1 - menas seek backwards, skipping one + * displayable record + * + * + * RETURNED: false is return if a displayable record was not found. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/5/95 Initial Revision + * + ***********************************************************************/ +static Boolean SeekRecord (UInt16 * indexP, Int16 offset, Int16 direction) +{ + DmSeekRecordInCategory (MemoDB, indexP, offset, direction, CurrentCategory); + if (DmGetLastErr()) return (false); + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: ChangeCategory + * + * DESCRIPTION: This routine updates the global varibles that keep track + * of category information. + * + * PARAMETERS: category - new category (index) + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 3/10/95 Initial Revision + * + ***********************************************************************/ +static void ChangeCategory (UInt16 category) +{ + if (ShowAllCategories) + MemosInCategory = DmNumRecordsInCategory (MemoDB, dmAllCategories); + else + MemosInCategory = DmNumRecordsInCategory (MemoDB, category); + + CurrentCategory = category; + TopVisibleRecord = 0; +/* TRG */ + selectedItem = -1; +/* end TRG */ +} + + +/*********************************************************************** + * + * FUNCTION: DrawMemoTitle + * + * DESCRIPTION: This routine draws the title of the specified memo. + * + * PARAMETERS: memo - pointer to a memo + * x - draw position + * y - draw position + * width - maximum width to draw. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 04/18/95 Initial Revision + * roger 07/27/95 Combined both cases + * kwk 05/15/99 Use Int'l code for truncation of title. + * + ***********************************************************************/ +static void DrawMemoTitle (Char * memo, Int16 x, Int16 y, Int16 width) +{ + Char * ptr = StrChr (memo, linefeedChr); + UInt16 titleLen = (ptr == NULL ? StrLen (memo) : (UInt16) (ptr - memo)); + if (FntWidthToOffset (memo, titleLen, width, NULL, NULL) == titleLen) + { + WinDrawChars (memo, titleLen, x, y); + } + else + { + Int16 titleWidth; + titleLen = FntWidthToOffset (memo, titleLen, width - FntCharWidth (chrEllipsis), NULL, &titleWidth); + WinDrawChars (memo, titleLen, x, y); + WinDrawChar (chrEllipsis, x + titleWidth, y); + } +} + + +/*********************************************************************** + * + * FUNCTION: ReplaceTwoColors + * + * DESCRIPTION: This routine does a selection or deselection effect by + * replacing foreground and background colors with a new pair + * of colors. In order to reverse the process, you must pass + * the colors in the opposite order, so that the current + * and new colors are known to this routine. This routine + * correctly handling the cases when two or more of these + * four colors are the same, but it requires that the + * affected area of the screen contains neither of the + * given NEW colors, unless these colors are the same as + * one of the old colors. + * + * PARAMETERS: rP - pointer to a rectangle to 'invert' + * cornerDiam - corner diameter + * oldForeground - UI color currently used for foreground + * oldBackground - UI color currently used for background + * newForeground - UI color that you want for foreground + * newBackground - UI color that you want for background + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * peter 05/19/00 Initial Revision + * + ***********************************************************************/ +static void ReplaceTwoColors (const RectangleType *rP, UInt16 cornerDiam, + UIColorTableEntries oldForeground, UIColorTableEntries oldBackground, + UIColorTableEntries newForeground, UIColorTableEntries newBackground) +{ + UInt8 oldForegroundIndex = UIColorGetTableEntryIndex(oldForeground); + UInt8 oldBackgroundIndex = UIColorGetTableEntryIndex(oldBackground); + UInt8 newForegroundIndex = UIColorGetTableEntryIndex(newForeground); + UInt8 newBackgroundIndex = UIColorGetTableEntryIndex(newBackground); + + WinPushDrawState(); + WinSetDrawMode(winSwap); + WinSetPatternType (blackPattern); + + if (newBackgroundIndex == oldForegroundIndex) + if (newForegroundIndex == oldBackgroundIndex) + { + // Handle the case when foreground and background colors change places, + // such as on black and white systems, with a single swap. + WinSetBackColor(oldBackgroundIndex); + WinSetForeColor(oldForegroundIndex); + WinPaintRectangle(rP, cornerDiam); + } + else + { + // Handle the case when the old foreground and the new background + // are the same, using two swaps. + WinSetBackColor(oldForegroundIndex); + WinSetForeColor(oldBackgroundIndex); + WinPaintRectangle(rP, cornerDiam); + WinSetBackColor(oldBackgroundIndex); + WinSetForeColor(newForegroundIndex); + WinPaintRectangle(rP, cornerDiam); + } + else if (oldBackgroundIndex == newForegroundIndex) + { + // Handle the case when the old background and the new foreground + // are the same, using two swaps. + WinSetBackColor(newForegroundIndex); + WinSetForeColor(oldForegroundIndex); + WinPaintRectangle(rP, cornerDiam); + WinSetBackColor(newBackgroundIndex); + WinSetForeColor(oldForegroundIndex); + WinPaintRectangle(rP, cornerDiam); + } + else + { + // Handle the case when no two colors are the same, as is typically the case + // on color systems, using two swaps. + WinSetBackColor(oldBackgroundIndex); + WinSetForeColor(newBackgroundIndex); + WinPaintRectangle(rP, cornerDiam); + WinSetBackColor(oldForegroundIndex); + WinSetForeColor(newForegroundIndex); + WinPaintRectangle(rP, cornerDiam); + } + + WinPopDrawState(); +} + + +/*********************************************************************** + * + * FUNCTION: Search + * + * DESCRIPTION: This routine searchs the memo database for records + * containing the string passed. + * + * PARAMETERS: findParams - text search parameter block + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 04/18/95 Initial Revision + * roger 07/26/95 converted to modern search mechanism + * kwk 05/15/99 Use TxtFindString, save match length in custom param. + * jmp 10/01/99 Changed call to DmOpenDatabaseByTypeCreator() to + * MemoGetDatabase(). + * jmp 10/21/99 Previous change caused bug #22965, but previous code + * caused yet another problem. Fixed #22965 by using + * everyone else's way: Call DmGetNextDatabaseByTypeCreator() + * first, then call DmOpenDatabase() if all is well. + * + ***********************************************************************/ +static void Search (FindParamsPtr findParams) +{ + UInt16 pos; + Char * header; + UInt16 recordNum; + MemHandle recordH; + MemHandle headerStringH; + RectangleType r; + Boolean done; + Boolean match; + DmOpenRef dbP; + DmSearchStateType searchState; + Err err; + UInt16 cardNo = 0; + LocalID dbID; + MemoDBRecordPtr memoRecP; + UInt32 longPos; + UInt16 matchLength; + + // Find the application's data file. + err = DmGetNextDatabaseByTypeCreator (true, &searchState, memoDBType, + sysFileCMemo, true, &cardNo, &dbID); + if (err) + { + findParams->more = false; + return; + } + + // Open the Memo database. + dbP = DmOpenDatabase(cardNo, dbID, findParams->dbAccesMode); + if (!dbP) + { + findParams->more = false; + return; + } + + // Display the heading line. + headerStringH = DmGetResource(strRsc, FindMemoHeaderStr); + header = MemHandleLock(headerStringH); + done = FindDrawHeader(findParams, header); + MemHandleUnlock(headerStringH); + DmReleaseResource(headerStringH); + if (done) + goto Exit; + + // Search the memos for the "find" string. + recordNum = findParams->recordNum; + while (true) + { + // Because applications can take a long time to finish a find when + // the result may be on the screen or for other reasons, users like + // to be able to stop the find. Stop the find if an event is pending. + // This stops if the user does something with the device. Because + // this call slows winDown the search we perform it every so many + // records instead of every record. The response time should still + // be Int16 without introducing much extra work to the search. + + // Note that in the implementation below, if the next 16th record is + // secret the check doesn't happen. Generally this shouldn't be a + // problem since if most of the records are secret then the search + // won't take long anyways! + if ((recordNum & 0x000f) == 0 && // every 16th record + EvtSysEventAvail(true)) + { + // Stop the search process. + findParams->more = true; + break; + } + + recordH = DmQueryNextInCategory (dbP, &recordNum, dmAllCategories); + + // Have we run out of records? + if (! recordH) + { + findParams->more = false; + break; + } + + memoRecP = MemHandleLock (recordH); + + // Search for the string passed, if it's found display the title + // of the memo. + match = TxtFindString (&(memoRecP->note), findParams->strToFind, &longPos, &matchLength); + pos = longPos; + + if (match) + { + // Add the match to the find paramter block, if there is no room to + // display the match the following function will return true. + done = FindSaveMatch (findParams, recordNum, pos, 0, matchLength, cardNo, dbID); + + if (!done) + { + // Get the bounds of the region where we will draw the results. + FindGetLineBounds (findParams, &r); + + // Display the title of the description. + DrawMemoTitle (&(memoRecP->note), r.topLeft.x+1, r.topLeft.y, + r.extent.x-2); + + findParams->lineNumber++; + } + } + + MemHandleUnlock(recordH); + if (done) break; + + recordNum++; + } + +Exit: + DmCloseDatabase (dbP); +} + + +/*********************************************************************** + * + * FUNCTION: GoToItem + * + * DESCRIPTION: This routine is an entry point of the memo application. + * It is generally called as the result of hitting a + * "Go to" button in the text search dialog. The record + * identifies by the parameter block passed will be display, + * with the character range specified highlighted. + * + * PARAMETERS: goToParams - parameter block that identifies the record to + * display. + * launchingApp - true if the application is being launched. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 06/06/95 Initial Revision + * roger 07/26/95 converted to modern search mechanism + * kwk 05/15/99 Use saved match length in matchCustom field, so + * that it works with Japanese. + * + ***********************************************************************/ +static void GoToItem (GoToParamsPtr goToParams, Boolean launchingApp) +{ + UInt16 recordNum; + UInt16 attr; + UInt32 uniqueID; + EventType event; + + + recordNum = goToParams->recordNum; + if (!DmQueryRecord(MemoDB, recordNum)) + { + // Record isn't accessible. This can happen when receiving a beam while in the + // Memo New form. This prevents a fatal alert, but doesn't fix the off-by-one + // error. (See DOLATER in sysAppLaunchCmdExgReceiveData case.) + if (!SeekRecord(&recordNum, 0, dmSeekBackward)) + if (!SeekRecord(&recordNum, 0, dmSeekForward)) + { + FrmAlert(secGotoInvalidRecordAlert); + FrmGotoForm(ListView); + return; + } + } + DmRecordInfo(MemoDB, recordNum, &attr, &uniqueID, NULL); + if ((attr & dmRecAttrSecret) && PrivateRecordVisualStatus == maskPrivateRecords) + { + FrmAlert(secGotoInvalidRecordAlert); + FrmGotoForm(ListView); + return; + } + + // Make the item the first item displayed. + TopVisibleRecord = recordNum; + + // Change the current category if necessary. + if (CurrentCategory != dmAllCategories) + { + ChangeCategory (attr & dmRecAttrCategoryMask); + } + + + // If the application is already running, close all open forms. This + // may cause in the database record to be reordered, so we'll find the + // records index by its unique id. + if (! launchingApp) + { + FrmCloseAllForms (); + DmFindRecordByID (MemoDB, uniqueID, &recordNum); + } + + + // Send an event to goto a form and select the matching text. + MemSet (&event, sizeof(EventType), 0); + + event.eType = frmLoadEvent; + event.data.frmLoad.formID = EditView; + EvtAddEventToQueue (&event); + + event.eType = frmGotoEvent; + event.data.frmGoto.recordNum = recordNum; + event.data.frmGoto.matchPos = goToParams->matchPos; + event.data.frmGoto.matchLen = goToParams->matchCustom; + event.data.frmGoto.matchFieldNum = goToParams->matchFieldNum; + event.data.frmGoto.formID = EditView; + EvtAddEventToQueue (&event); + + CurrentView = EditView; +} + + +/*********************************************************************** + * + * FUNCTION: CreateRecord + * + * DESCRIPTION: This routine creates a new memo record. + * + * PARAMETERS: none + * + * RETURNED: true if the record was sucessfully created. + * + * HISTORY: + * 10/03/95 art Created by Art Lamb. + * 10/11/95 kcr Set initial graffiti upshift. + * 09/25/99 kwk No longer take initial character parameter. + * 10/29/99 jmp Eliminate compiler's "has no side-effect" warning. + * + ***********************************************************************/ +static Boolean CreateRecord (void) +{ + MemPtr p; + Char zero = 0; + UInt32 offset = 0; + UInt16 attr = dmUnfiledCategory; + UInt16 index; + MemHandle memoRec; + + // Add a new record at the end of the database. + index = DmNumRecords (MemoDB); + memoRec = DmNewRecord (MemoDB, &index, newMemoSize); + + // If the allocate failed, display a warning. + if (! memoRec) + { + FrmAlert (DeviceFullAlert); + return (false); + } + + + p = MemHandleLock (memoRec); + + // Null terminate the new memo string. + DmWrite (p, offset, &zero, sizeof(Char)); + + MemPtrUnlock (p); + + // Set the category of the new record to the current category. + DmRecordInfo (MemoDB, index, &attr, NULL, NULL); + attr &= ~dmRecAttrCategoryMask; + if (CurrentCategory != dmAllCategories) + attr |= CurrentCategory; + DmSetRecordInfo (MemoDB, index, &attr, NULL); + + CurrentRecord = index; + MemosInCategory++; + + DmReleaseRecord (MemoDB, index, true); + + + // Set the graffiti state for an initial upshift of the + // first character of a new memo. + //GrfSetState (false, false, true); + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: DeleteRecord + * + * DESCRIPTION: This routine deletes the specified memo + * + * PARAMETERS: index - index of record to delete + * + * RETURNED: true if the record was sucessfully deleted. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/30/95 Initial Revision + * + ***********************************************************************/ +static Boolean DeleteRecord (UInt16 index) +{ + UInt16 ctlIndex; + UInt16 buttonHit; + FormPtr alert; + Boolean saveBackup; + + // Display an alert to confirm the delete operation. + alert = FrmInitForm (DeleteMemoDialog); + +/* TRG */ + if (vgaExists) + { + VgaScreenModeType mode; + VgaRotateModeType rotation; + + VgaGetScreenMode(&mode, &rotation); + + if((mode == screenMode1To1) && ((rotation == rotateModeNone) || (rotation == rotateMode180))) + VgaFormModify(alert, vgaFormModify160To240); + } +/* end TRG */ + + + ctlIndex = FrmGetObjectIndex (alert, DeleteMemoSaveBackup); + FrmSetControlValue (alert, ctlIndex, SaveBackup); + buttonHit = FrmDoDialog (alert); + saveBackup = FrmGetControlValue (alert, ctlIndex);; + + FrmDeleteForm (alert); + + if (buttonHit != DeleteMemoOk) + return (false); + + SaveBackup = saveBackup; + + // Delete or archive the record. + if (SaveBackup) + DmArchiveRecord (MemoDB, index); + else + DmDeleteRecord (MemoDB, index); + DmMoveRecord (MemoDB, index, DmNumRecords (MemoDB)); + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: SelectFont + * + * DESCRIPTION: This routine handles selection of a font in the List + * View. + * + * PARAMETERS: currFontID - id of current font + * + * RETURNED: id of new font + * + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/10/97 Initial Revision + * + ***********************************************************************/ +static FontID SelectFont (FontID currFontID) +{ + UInt16 formID; + FontID fontID; + + formID = (FrmGetFormId (FrmGetActiveForm ())); + + // Call the OS font selector to get the id of a font. + fontID = FontSelect (currFontID); + +/* TRG */ + if (vgaExists && (formID == ListView)) + { + FormPtr frm; + frm = FrmGetActiveForm(); + VgaTableUseBaseFont(FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, ListTable)), + !VgaIsVgaFont(fontID)); + } +/* end TRG */ + + + if (fontID != currFontID) + FrmUpdateForm (formID, updateFontChanged); + + return (fontID); +} + +/* TRG */ +// utility functions to move and resize form objects for the virtual silk screen +static void PrvMoveObject(FormPtr frmP, UInt16 objIndex, Coord x_diff, Coord y_diff, Boolean draw) +{ + Coord old_x, old_y; + + if(draw) + FrmHideObject(frmP, objIndex); + + FrmGetObjectPosition(frmP, objIndex, &old_x, &old_y); + FrmSetObjectPosition(frmP, objIndex, old_x + x_diff, old_y + y_diff); + + if(draw) + FrmShowObject(frmP, objIndex); +} + +static void PrvResizeObject(FormPtr frmP, UInt16 objIndex, Coord x_diff, Coord y_diff, Boolean draw) +{ + RectangleType r; + + if(draw) + FrmHideObject(frmP, objIndex); + + FrmGetObjectBounds(frmP, objIndex, &r); + r.extent.x += x_diff; + r.extent.y += y_diff; + FrmSetObjectBounds(frmP, objIndex, &r); + + if(draw) + FrmShowObject(frmP, objIndex); +} + +static UInt16 PrvFrmGetGSI(FormPtr frmP) +{ + UInt16 retval = -1; + UInt16 i, num; + + num = FrmGetNumberOfObjects(frmP); + + for (i=0;ieType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case PreferencesOkButton: + updateCode = PreferencesApply (); + FrmReturnToForm (ListView); + if (updateCode) + FrmUpdateForm (ListView, updateCode); + handled = true; + break; + + case PreferencesCancelButton: + FrmReturnToForm (ListView); + handled = true; + break; + + } + } + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); + PreferencesInit (); + FrmDrawForm (frm); + handled = true; + } + + return (handled); +} + + +#pragma mark ---- +/*********************************************************************** + * + * FUNCTION: DetailsSelectCategory + * + * DESCRIPTION: This routine handles selection, creation and deletion of + * categories form the Details Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: index of the selected category. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 03/10/95 Initial Revision + * gap 08/13/99 Update to use new constant categoryDefaultEditCategoryString. + * + ***********************************************************************/ +static UInt16 DetailsSelectCategory (UInt16* category) +{ + Char* name; + Boolean categoryEdited; + + name = (Char *)CtlGetLabel (GetObjectPtr (DetailsCategoryTrigger)); + + categoryEdited = CategorySelect (MemoDB, FrmGetActiveForm (), + DetailsCategoryTrigger, DetailsCategoryList, + false, category, name, 1, categoryDefaultEditCategoryString); + + return (categoryEdited); +} + + + +/*********************************************************************** + * + * FUNCTION: DetailsApply + * + * DESCRIPTION: This routine applies the changes made in the Details Dialog. + * + * PARAMETERS: category - new catagory + * + * RETURNED: code which indicates how the memo was changed, this + * code is sent as the update code, in the frmUpdate event. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 3/10/95 Initial Revision + * kcr 10/9/95 added 'private records' alert. + * + ***********************************************************************/ +static UInt16 DetailsApply (UInt16 category, Boolean categoryEdited) +{ + UInt16 attr; + UInt16 updateCode = 0; + Boolean dirty = false; + Boolean secret; + + + // Get the category and secret attribute of the current record. + DmRecordInfo (MemoDB, CurrentRecord, &attr, NULL, NULL); + + // Get the current setting of the secret checkbox. + secret = (CtlGetValue (GetObjectPtr (DetailsSecretCheckbox)) != 0); + + // Has the secret attribute was been changed? + if (((attr & dmRecAttrSecret) == dmRecAttrSecret) != secret) + { + if (secret) + { + attr |= dmRecAttrSecret; + if (PrivateRecordVisualStatus == showPrivateRecords) + FrmAlert (privateRecordInfoAlert); + } + else + attr &= ~dmRecAttrSecret; + dirty = true; + } + + + // Has the category been changed? + if (CurrentCategory != category) + { + attr &= ~dmRecAttrCategoryMask; + attr |= category; + dirty = true; + updateCode = updateCategoryChanged; + } + + + // If the current category was deleted, renamed, or merged with + // another category, then the list view needs to be redrawn. + if (categoryEdited) + { + CurrentCategory = category; + updateCode |= updateCategoryChanged; + } + + + if (dirty) + { + attr |= dmRecAttrDirty; + DmSetRecordInfo (MemoDB, CurrentRecord, &attr, NULL); + } + + return (updateCode); +} + + +/*********************************************************************** + * + * FUNCTION: DetailsInit + * + * DESCRIPTION: This routine initializes the Details Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 3/10/95 Initial Revision + * + ***********************************************************************/ +static void DetailsInit (void) +{ + UInt16 attr; + UInt16 category; + Char* name; + Boolean secret; + ControlPtr ctl; + +/* TRG */ + PrvVgaAdjustModalForm(FrmGetActiveForm()); +/* end TRG */ + + // Get the category and secret attribute of the current record. + DmRecordInfo (MemoDB, CurrentRecord, &attr, NULL, NULL); + category = attr & dmRecAttrCategoryMask; + secret = attr & dmRecAttrSecret; + + + // If the record is marked secret, turn on the secret checkbox. + ctl = GetObjectPtr (DetailsSecretCheckbox); + if (secret) + CtlSetValue (ctl, true); + else + CtlSetValue (ctl, false); + + + // Set the label of the category trigger. + ctl = GetObjectPtr (DetailsCategoryTrigger); + name = (Char *)CtlGetLabel (ctl); + CategoryGetName (MemoDB, category, name); + CategorySetTriggerLabel (ctl, name); +} + + +/*********************************************************************** + * + * FUNCTION: DetailsHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "Details + * Dialog Box". + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * + ***********************************************************************/ + +static Boolean DetailsHandleEvent (EventType * event) +{ + static UInt16 category; + static Boolean categoryEdited; + + UInt16 updateCode; + FormPtr frm; + Boolean handled = false; + + if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case DetailsOkButton: + updateCode = DetailsApply (category, categoryEdited); + FrmReturnToForm (EditView); + if (updateCode) + FrmUpdateForm (EditView, updateCode); + handled = true; + break; + + case DetailsCancelButton: + if (categoryEdited) + FrmUpdateForm (EditView, updateCategoryChanged); + FrmReturnToForm (EditView); + handled = true; + break; + + case DetailsDeleteButton: + if ( EditViewDeleteRecord ()) + { + frm = FrmGetActiveForm(); + FrmEraseForm (frm); + FrmDeleteForm (frm); + FrmCloseAllForms (); + FrmGotoForm (ListView); + } + handled = true; + break; + + + case DetailsCategoryTrigger: + categoryEdited = DetailsSelectCategory (&category) || categoryEdited; + handled = true; + break; + } + } + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); + DetailsInit (); + FrmDrawForm (frm); + category = CurrentCategory; + categoryEdited = false; + handled = true; + } + + return (handled); +} + + +#pragma mark ---- +/*********************************************************************** + * + * FUNCTION: EditViewSetTitle + * + * DESCRIPTION: This routine formats and sets the title of the Edit View. + * If the Edit View is visible, the new title is drawn. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * HISTORY: + * 02/21/95 art Created by Art Labm. + * 08/31/00 kwk Re-wrote to use TxtParamString, versus hard-coding + * order of elements using '#' in template string. + * 11/22/00 FPa Added DmReleaseResource() + * 11/28/00 CS Use FrmSetTitle instead of FrmCopyTitle and leave it + * allocated until EditViewExit. This removes the + * dependency that the form title in the resource has to + * be wide enough to accomodate the longest possible title. + * 11/30/00 FPa Fixed bug #46014 + * + ***********************************************************************/ +static void EditViewSetTitle (void) +{ + MemHandle titleTemplateH; + Char * titleTemplateP; + Char * title; + Char * oldTitle; + Char posStr[maxStrIToALen + 1]; + Char totalStr[maxStrIToALen + 1]; + UInt16 pos; + FormType* formP; + + formP = FrmGetFormPtr(EditView); + + // If there's an old title, we must free it; nevertheless FrmSetTitle() uses the old title -> we need to free it *after* having called FrmSetTitle() + oldTitle = (Char*)FrmGetTitle(formP); + + // Format as strings, the memo's postion within its category, and + // the total number of memos in the category. + pos = DmPositionInCategory( MemoDB,CurrentRecord, ShowAllCategories ? dmAllCategories : CurrentCategory); + StrIToA(posStr, pos+1); + StrIToA(totalStr, MemosInCategory); + + titleTemplateH = DmGetResource(strRsc, EditTitleString); + titleTemplateP = MemHandleLock(titleTemplateH); + title = TxtParamString(titleTemplateP, posStr, totalStr, NULL, NULL); // title needs to be freed + + FrmSetTitle(formP, title); + + if (oldTitle != 0) + MemPtrFree(oldTitle); + + MemHandleUnlock(titleTemplateH); + DmReleaseResource(titleTemplateH); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewSelectCategory + * + * DESCRIPTION: This routine recategorizes a memo in the "Edit View". + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * The following global variables are modified: + * CurrentCategory + * CategoryName + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 10/03/95 Initial Revision + * grant 86/29/99 Adjust MemosInCategory when the record is private + * gap 08/13/99 Update to use new constant categoryDefaultEditCategoryString. + * + ***********************************************************************/ +static void EditViewSelectCategory (void) +{ + UInt16 attr; + FormPtr frm; + UInt16 category; + Boolean categorySelected; + Boolean categoryEdited; + + + // Get the current category. + DmRecordInfo (MemoDB, CurrentRecord, &attr, NULL, NULL); + category = attr & dmRecAttrCategoryMask; + + // Process the category popup list. + frm = FrmGetActiveForm(); + categoryEdited = CategorySelect (MemoDB, frm, EditCategoryTrigger, + EditCategoryList, false, &category, CategoryName, 1, categoryDefaultEditCategoryString); + + + categorySelected = category != (attr & dmRecAttrCategoryMask); + + // If a different category was selected, set the category field + // in the new record. + if (categorySelected) + { + // Change the category of the record. + DmRecordInfo (MemoDB, CurrentRecord, &attr, NULL, NULL); + attr &= ~dmRecAttrCategoryMask; + attr |= category | dmRecAttrDirty; + DmSetRecordInfo (MemoDB, CurrentRecord, &attr, NULL); + } + + + // If the current category was changed or the name of the category + // was edited, draw the title. + if (categoryEdited || categorySelected) + { + ChangeCategory (category); + + // If the record is secret and secret records are hidden, then the record isn't + // accounted for by MemosInCategory. Adjust it, and EditViewSaveRecord will + // adjust when done with the record. + if ((PrivateRecordVisualStatus == hidePrivateRecords) && (attr & dmRecAttrSecret)) + MemosInCategory++; + + EditViewSetTitle (); + } +} + + +/*********************************************************************** + * + * FUNCTION: EditViewUpdateScrollBar + * + * DESCRIPTION: This routine update the scroll bar. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 07/01/96 Initial Revision + * gap 11/02/96 Fix case where field and scroll bars get out of sync + * + ***********************************************************************/ +static void EditViewUpdateScrollBar () +{ + UInt16 scrollPos; + UInt16 textHeight; + UInt16 fieldHeight; + Int16 maxValue; + FieldPtr fld; + ScrollBarPtr bar; + + fld = GetObjectPtr (EditMemoField); + bar = GetObjectPtr (EditMemoScrollBar); + + FldGetScrollValues (fld, &scrollPos, &textHeight, &fieldHeight); + + if (textHeight > fieldHeight) + { + // On occasion, such as after deleting a multi-line selection of text, + // the display might be the last few lines of a field followed by some + // blank lines. To keep the current position in place and allow the user + // to "gracefully" scroll out of the blank area, the number of blank lines + // visible needs to be added to max value. Otherwise the scroll position + // may be greater than maxValue, get pinned to maxvalue in SclSetScrollBar + // resulting in the scroll bar and the display being out of sync. + maxValue = (textHeight - fieldHeight) + FldGetNumberOfBlankLines (fld); + } + else if (scrollPos) + maxValue = scrollPos; + else + maxValue = 0; + + SclSetScrollBar (bar, scrollPos, 0, maxValue, fieldHeight-1); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewLoadRecord + * + * DESCRIPTION: This routine loads a memo record into the Edit View form. + * + * PARAMETERS: frm - pointer to the Edit View form + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * roger 6/24/99 Fixup MemosInCategory when the record is private + * peter 4/25/00 Add support for un-masking just the selected record. + * + ***********************************************************************/ +static void EditViewLoadRecord (FormPtr frm) +{ + UInt16 attr; + FieldPtr fld; + ControlPtr ctl; + MemHandle memoRec; + + Boolean capsLock, numLock, autoShifted; + UInt16 tempShift; + if ((GrfGetState(&capsLock, &numLock, &tempShift, &autoShifted) == 0) + && (autoShifted)) + { + GrfSetState(capsLock, numLock, false); + } + + // Get a pointer to the memo field. + fld = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, EditMemoField)); + + DmRecordInfo (MemoDB, CurrentRecord, &attr, NULL, NULL); + + // Get the current record. + memoRec = DmGetRecord (MemoDB, CurrentRecord); + ErrFatalDisplayIf ((! memoRec), "Bad record"); + + // Set the font used by the memo field. + FldSetFont (fld, EditFont); + + FldSetTextHandle (fld, memoRec); + FldSetScrollPosition (fld, EditScrollPosition); + + // Set the global variable that keeps track of the current category + // to the category of the current record. + CurrentCategory = attr & dmRecAttrCategoryMask; + + // If the record is secret and secret records are hidden, then the record isn't + // accounted for by MemosInCategory. Adjust it, and EditViewSaveRecord will + // adjust when done with the record. + if ((PrivateRecordVisualStatus == hidePrivateRecords) && (attr & dmRecAttrSecret)) + MemosInCategory++; + + // Set the view's title + EditViewSetTitle (); + + // Set the label that contains the note's category. + ctl = GetObjectPtr (EditCategoryTrigger); + CategoryGetName (MemoDB, CurrentCategory, CategoryName); + CategorySetTriggerLabel (ctl, CategoryName); + + EditViewUpdateScrollBar (); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewSaveRecord + * + * DESCRIPTION: This routine save a memo record to the memo database or + * deletes it if it's empty. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * kcr 11/16/95 use DmReleaseRecord to set dirty attribute + * jmp 9/29/99 Use FrmGetFormPtr() & FrmGetObjectIndex() instead of + * GetObjectPtr() because GetObjectPtr() calls FrmGetActiveForm(), + * and FrmGetActiveForm() may return a form that isn't the one we + * want when other forms are up when we are called. + * Fixes bug #22418. + * + ***********************************************************************/ +static void EditViewSaveRecord (void) +{ + UInt16 attr; + Char * ptr; + Boolean empty; + Boolean dirty; + FieldPtr fld; + FormPtr frm; + + // Find out if the field has been modified or if it's empty. + frm = FrmGetFormPtr (EditView); + fld = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, EditMemoField)); + ptr = FldGetTextPtr (fld); + dirty = FldDirty (fld); + empty = (*ptr == 0); + + FldReleaseFocus (fld); + + // Release any free space in the memo field. + FldCompactText (fld); + + // Clear the handle value in the field, otherwise the handle + // will be free when the form is disposed of. + FldSetTextHandle (fld, 0); + + // If there's data in an existing record, mark it dirty if + // necessary and release it. + if (! empty) + { + DmRecordInfo (MemoDB, CurrentRecord, &attr, NULL, NULL); + + if (PrivateRecordVisualStatus == hidePrivateRecords && (attr & dmRecAttrSecret)) + MemosInCategory--; + + DmReleaseRecord (MemoDB, CurrentRecord, dirty); + + // Move the current record to the correct sort position. + if (dirty) + MemoSortRecord (MemoDB, &CurrentRecord); + } + + // If the record is empty, delete it. + else + { + if (dirty) + { + DmDeleteRecord (MemoDB, CurrentRecord); + DmMoveRecord (MemoDB, CurrentRecord, DmNumRecords (MemoDB)); + } + else + DmRemoveRecord (MemoDB, CurrentRecord); + + CurrentRecord = noRecordSelected; + MemosInCategory--; + } + + ErrNonFatalDisplayIf(MemosInCategory > DmNumRecords(MemoDB), "invalid MemosInCategory"); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewChangeFont + * + * DESCRIPTION: This routine redisplay the memo in the font specified. + * It is called when one of the font push-buttons is presed. + * + * PARAMETERS: controlID - id to button pressed. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * kcr 10/20/95 handles two-button font change mechanism + * + ***********************************************************************/ +static void EditViewChangeFont (void) +{ + FontID fontID; + FieldPtr fld; + + // Call the OS font selector to get the id of a font. + fontID = FontSelect (EditFont); + + if (fontID != EditFont) + { + EditFont = fontID; + + // FldSetFont will redraw the field if it is visible. + fld = GetObjectPtr (EditMemoField); + FldSetFont (fld, fontID); + } + + EditViewUpdateScrollBar (); +} + + + +/*********************************************************************** + * + * FUNCTION: EditViewDeleteRecord + * + * DESCRIPTION: This routine deletes a memo record.. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * + ***********************************************************************/ +static Boolean EditViewDeleteRecord (void) +{ + FormPtr frm; + FieldPtr fld; + Char * ptr; + UInt16 ctlIndex; + UInt16 buttonHit; + FormPtr alert; + Boolean empty; + Boolean saveBackup; + + frm = FrmGetFormPtr (EditView); + fld = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, EditMemoField)); + + // Find out if the field is empty. + ptr = FldGetTextPtr (fld); + empty = (*ptr == 0); + + // Display an alert to confirm the operation. + if (!empty) + { + alert = FrmInitForm (DeleteMemoDialog); + +/* TRG */ + PrvVgaAdjustModalForm(alert); +/* end TRG */ + + ctlIndex = FrmGetObjectIndex (alert, DeleteMemoSaveBackup); + FrmSetControlValue (alert, ctlIndex, SaveBackup); + buttonHit = FrmDoDialog (alert); + saveBackup = FrmGetControlValue (alert, ctlIndex);; + + FrmDeleteForm (alert); + + if (buttonHit == DeleteMemoCancel) + return (false); + + SaveBackup = saveBackup; + } + + // Clear the handle value in the field, otherwise the handle + // will be free when the form is disposed of. + FldSetTextHandle (fld, 0); + + // Delete or archive the record. + if (empty && (! FldDirty (fld))) + { + DmRemoveRecord (MemoDB, CurrentRecord); + } + else + { + if (SaveBackup) + DmArchiveRecord (MemoDB, CurrentRecord); + else + DmDeleteRecord (MemoDB, CurrentRecord); + DmMoveRecord (MemoDB, CurrentRecord, DmNumRecords (MemoDB)); + } + + MemosInCategory--; + CurrentRecord = noRecordSelected; + + ErrNonFatalDisplayIf(MemosInCategory > DmNumRecords(MemoDB), "invalid MemosInCategory"); + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: True if we handled the command. + * + * HISTORY: + * 03/29/95 art Created by Art Lamb. + * 11/07/95 kcr converted to common about box + * 08/21/99 kwk Deleted page top/bottom commands. + * 11/04/99 jmp To prevent other sublaunch issues, remind ourselves + * that we've sublaunched already into PhoneNumberLookup(). + * + ***********************************************************************/ +static Boolean EditViewDoCommand (UInt16 command) +{ + FieldPtr fld; + FormPtr frm; + Boolean handled = true; + + switch (command) + { + case NewMemoCmd: + EditViewSaveRecord (); + CreateRecord (); + EditScrollPosition = 0; + if (CurrentRecord != noRecordSelected) + { + EditViewLoadRecord (FrmGetActiveForm ()); + fld = GetFocusObjectPtr (); + if (fld) FldGrabFocus (fld); + } + else + FrmGotoForm (ListView); + break; + + case DeleteMemoCmd: + if (EditViewDeleteRecord ()) + FrmGotoForm (ListView); + break; + + case BeamMemoCmd: + case SendMemoCmd: + fld = GetObjectPtr (EditMemoField); + if (FldGetTextLength(fld) > 0) + { + EditViewSaveRecord(); + MemoSendRecord(MemoDB, CurrentRecord, (command == BeamMemoCmd ? exgBeamPrefix : exgSendPrefix)); + + // Redisplay the record. If the IR loopback mechanism sends the + // record to this app the goto action code closes all forms and + // send a frmGotoEvent. Load the record again only if the form + // still exits. + frm = FrmGetActiveForm (); + if (frm) + EditViewLoadRecord (frm); + } + else + FrmAlert(NoDataToBeamAlert); + break; + /* + case BeamCategoryCmd: + case SendCategoryCmd: + fld = GetObjectPtr (EditMemoField); + if (FldGetTextLength(fld) > 0) + { + FldCompactText (fld); + MemoSendCategory(MemoDB, CurrentCategory, (command == BeamCategoryCmd ? exgBeamPrefix : exgSendPrefix), (command == BeamCategoryCmd ? NoDataToBeamAlert : NoDataToSendAlert)); + } + else + FrmAlert(NoDataToBeamAlert); + break; + */ + + case EditOptionsFontsCmd: + EditViewChangeFont (); + break; + + case EditOptionPhoneLookupCmd: + fld = GetObjectPtr (EditMemoField); + if (fld) + { + InPhoneLookup = true; + PhoneNumberLookup (fld); + InPhoneLookup = false; + } + break; + + case EditOptionsAboutCmd: + AbtShowAbout (sysFileCMemo); + break; + + default: + handled = false; + } + + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewScroll + * + * DESCRIPTION: This routine scrolls the memo edit view a page or a + * line at a time. + * + * PARAMETERS: linesToScroll - the number of lines to scroll, + * positive for winDown, + * negative for winUp + * updateScrollbar - force a scrollbar update? + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/1/96 Initial Revision + * grant 2/4/99 Use EditViewUpdateScrollBar() + * + ***********************************************************************/ +static void EditViewScroll (Int16 linesToScroll, Boolean updateScrollbar) +{ + UInt16 blankLines; + FieldPtr fld; + + fld = GetObjectPtr (EditMemoField); + blankLines = FldGetNumberOfBlankLines (fld); + + if (linesToScroll < 0) + FldScrollField (fld, -linesToScroll, winUp); + else if (linesToScroll > 0) + FldScrollField (fld, linesToScroll, winDown); + + // If there were blank lines visible at the end of the field + // then we need to update the scroll bar. + if (blankLines || updateScrollbar) + { + ErrNonFatalDisplayIf(blankLines && linesToScroll > 0, "blank lines when scrolling winDown"); + + EditViewUpdateScrollBar(); + } +} + + +/*********************************************************************** + * + * FUNCTION: EditViewPageScroll + * + * DESCRIPTION: This routine scrolls the message a page winUp or winDown. + * When the top of a memo is visible, scrolling up will + * display the display the botton of the previous memo. + * If the bottom of a memo is visible, scrolling down will + * display the top of the next memo. + * + * PARAMETERS: direction winUp or winDown + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/1/96 Initial Revision + * grant 2/4/99 Use EditViewScroll() to do actual scrolling. + * + ***********************************************************************/ +static void EditViewPageScroll (WinDirectionType direction) +{ + Int16 seekDirection; + UInt16 category; + UInt16 recordNum; + UInt32 uniqueID; + UInt16 linesToScroll; + FieldPtr fld; + UInt16 attr; + + fld = GetObjectPtr (EditMemoField); + + if (FldScrollable (fld, direction)) + { + linesToScroll = FldGetVisibleLines (fld) - 1; + + if (direction == winUp) + linesToScroll = -linesToScroll; + + EditViewScroll(linesToScroll, true); + + return; + } + + + // Move to the next or previous memo. + if (direction == winUp) + { + seekDirection = dmSeekBackward; + EditScrollPosition = maxFieldTextLen; + } + else + { + seekDirection = dmSeekForward; + EditScrollPosition = 0; + } + + if (ShowAllCategories) + category = dmAllCategories; + else + category = CurrentCategory; + + recordNum = CurrentRecord; + + //while to skip masked records. Even if the body never executes, we'll have done a DmSeekRecordInCategory + while (!DmSeekRecordInCategory (MemoDB, &recordNum, 1, seekDirection, category) && + !DmRecordInfo (MemoDB, recordNum, &attr, NULL, NULL) && + ((attr & dmRecAttrSecret) && PrivateRecordVisualStatus == maskPrivateRecords)) + { + } + + if (recordNum == CurrentRecord) return; + + // Don't show first/last record if it's private and we're masking. + if (!DmRecordInfo (MemoDB, recordNum, &attr, NULL, NULL) && + ((attr & dmRecAttrSecret) && PrivateRecordVisualStatus == maskPrivateRecords)) + return; + + SndPlaySystemSound (sndInfo); + + // Saving the current record may cause it to move if the records are + // sorted alphabeticly. + DmRecordInfo (MemoDB, recordNum, NULL, &uniqueID, NULL); + EditViewSaveRecord (); + DmFindRecordByID (MemoDB, uniqueID, &CurrentRecord); + + EditViewLoadRecord (FrmGetActiveForm ()); + FldGrabFocus (fld); + +} + + +/*********************************************************************** + * + * FUNCTION: EditViewExit + * + * DESCRIPTION: This routine is call when the Edit View is exited. It + * releases any memory allocated for the Edit View. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 3/17/95 Initial Revision + * + ***********************************************************************/ +static void EditViewExit (void) +{ + FormPtr frm; + void * title; + + // Free the title string. + frm = FrmGetActiveForm (); + title = (void *)FrmGetTitle (frm); + if (title) + { + MemPtrFree(title); + } +} + + +/*********************************************************************** + * + * FUNCTION: EditViewInit + * + * DESCRIPTION: This routine initials the Edit View form. + * + * PARAMETERS: frm - pointer to the Edit View form. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 3/31/95 Initial Revision + * art 7/1/96 Set field hasScrollBar attribute + * FPa 11/30/96 Set title to 0 + * + ***********************************************************************/ +static void EditViewInit (FormPtr frm) +{ + FieldPtr fld; + FieldAttrType attr; + + + // Have the field send event to maintain the scroll bar. + fld = GetObjectPtr (EditMemoField); + FldGetAttributes (fld, &attr); + attr.hasScrollBar = true; + FldSetAttributes (fld, &attr); + + FrmSetTitle(frm, 0); // To avoid a crash into EditViewSetTitle when trying to free the old title + + EditViewLoadRecord (frm); + + CurrentView = EditView; +} + + +/*********************************************************************** + * + * FUNCTION: EditViewUpdateDisplay + * + * DESCRIPTION: This routine update the display of the edit view + * + * PARAMETERS: updateCode - a code that indicated what changes have been + * made to the view. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 10/3/95 Initial Revision + * + ***********************************************************************/ +static Boolean EditViewUpdateDisplay (UInt16 updateCode) +{ + UInt16 attr; + UInt16 category; + + if (updateCode == updateCategoryChanged) + { + DmRecordInfo (MemoDB, CurrentRecord, &attr, NULL, NULL); + category = attr & dmRecAttrCategoryMask; + ChangeCategory (category); + + // If we are editing a secret record and secret records are hidden + // then increment the record count so that the correct record count + // is shown. + if (PrivateRecordVisualStatus == hidePrivateRecords && (attr & dmRecAttrSecret)) + MemosInCategory++; + + // Set the title of the edit view. + EditViewSetTitle (); + + // Set the label of the category trigger. + CategoryGetName (MemoDB, CurrentCategory, CategoryName); + CategorySetTriggerLabel (GetObjectPtr (EditCategoryTrigger), + CategoryName); + return (true); + } + + return (false); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "Edit View" + * of the Memo application. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handled and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 02/21/95 Initial Revision. + * kwk 10/04/98 Explicitly disable Graffiti auto-shift if we get + * a printable key-down event. + * kwk 11/21/98 Handle cmd keys in separate code block, so TxtCharIsPrint + * doesn't get called w/virtual key codes. + * gap 10/27/00 change the command bar initialization to allow field + * code to add cut, copy, paste, & undo commands as + * appropriate rather than adding a fixed set of selections. + * CS 11/28/00 Call EditViewExit in response to frmCloseEvent. + * + ***********************************************************************/ +static Boolean EditViewHandleEvent (EventType * event) +{ + FormPtr frm; + Boolean handled = false; + FieldPtr fldP; + UInt32 numLibs; + + + if (event->eType == keyDownEvent) + { + if (TxtCharIsHardKey(event->data.keyDown.modifiers, event->data.keyDown.chr)) + { + EditViewSaveRecord (); + FrmGotoForm (ListView); + handled = true; + } + + else if (EvtKeydownIsVirtual(event)) + { + if (event->data.keyDown.chr == vchrPageUp) + { + EditViewPageScroll (winUp); + handled = true; + } + + else if (event->data.keyDown.chr == vchrPageDown) + { + EditViewPageScroll (winDown); + handled = true; + } + + // Send data key presed? + else if (event->data.keyDown.chr == vchrSendData) + { + if (FldGetTextLength(GetObjectPtr (EditMemoField)) > 0) + { + EditViewSaveRecord(); + MemoSendRecord(MemoDB, CurrentRecord, exgBeamPrefix); + + // Redisplay the record. If the IR loopback mechanism sends the + // record to this app the goto action code closes all forms and + // send a frmGotoEvent. Load the record again only if the form + // still exits. + frm = FrmGetActiveForm (); + if (frm) + EditViewLoadRecord (frm); + } + else + FrmAlert(NoDataToBeamAlert); + handled = true; + } +/* TRG */ + else if ((event->data.keyDown.chr == chrEscape) || + (event->data.keyDown.chr == chrCarriageReturn)) + { + EditViewSaveRecord (); + FrmGotoForm (ListView); + handled = true; + } +/* end TRG */ + } + + // If we get a printable character, then we can assume that any Graffiti + // auto-shifting is finished, so it's safe to turn it off. This solves the + // problem of a re-queued keydown event (e.g. when in list view & writing + // a character -> generate a new memo) not turning off the temp shift state + // because it wasn't created by Graffiti. + // DOLATER kwk - figure out if this is the best way to handle auto-shift + // problem with creation of memo from list view (input method coordination). + // Better would be for the field code to turn off auto-shift when it handles + // insertion or a keydown event. + + // LFe: This is done now by the field. + /* + else if (TxtCharIsPrint(event->data.keyDown.chr)) + { + Boolean capsLock, numLock, autoShifted; + UInt16 tempShift; + + if ((GrfGetState(&capsLock, &numLock, &tempShift, &autoShifted) == 0) + && (autoShifted)) + { + GrfSetState(capsLock, numLock, false); + } + } + */ + } + + else if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case EditCategoryTrigger: + EditViewSelectCategory (); + handled = true; + break; + + case EditDoneButton: + EditViewSaveRecord (); + FrmGotoForm (ListView); + handled = true; + break; + + case EditDetailsButton: + FrmPopupForm (DetailsDialog); + handled = true; + break; + } + } + + + else if (event->eType == menuOpenEvent) + { + if (ExgGetRegisteredApplications(NULL, &numLibs, NULL, NULL, exgRegSchemeID, exgSendScheme) || !numLibs) + MenuHideItem(SendMemoCmd); + else + MenuShowItem(SendMemoCmd); + // don't set handled = true + } + + else if (event->eType == menuEvent) + { + handled = EditViewDoCommand (event->data.menu.itemID); + } + + + // Add the buttons that we want available on the command bar, based on the current context + else if (event->eType == menuCmdBarOpenEvent) + { + UInt16 startPos, endPos; + FieldType* fldP; + + fldP = GetObjectPtr (EditMemoField); + FldGetSelection(fldP, &startPos, &endPos); + + if (startPos == endPos) // there's no highlighted text + { + // Call directly Field event handler so that System Edit buttons are added + FldHandleEvent(fldP, event); + + // Beam on the left + MenuCmdBarAddButton(menuCmdBarOnLeft, BarBeamBitmap, menuCmdBarResultMenuItem, BeamMemoCmd, 0); + + // Delete on the Right + MenuCmdBarAddButton(menuCmdBarOnRight, BarDeleteBitmap, menuCmdBarResultMenuItem, DeleteMemoCmd, 0); + + // Prevent the field package to automatically add cut, copy, paste, and undo buttons as applicable + // since it was done previously + event->data.menuCmdBarOpen.preventFieldButtons = true; + } + + // don't set handled to true; this event must fall through to the system. + } + + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); +/* TRG */ + if (vgaExists) + VgaFormModify(frm, vgaFormModify160To240); + EditViewResizeForm(frm, false); +/* end TRG */ + EditViewInit (frm); + FrmDrawForm (frm); + FrmSetFocus (frm, FrmGetObjectIndex (frm, EditMemoField)); + handled = true; + } + + + else if (event->eType == frmGotoEvent) + { + frm = FrmGetActiveForm (); +/* TRG */ + if (vgaExists) + VgaFormModify(frm, vgaFormModify160To240); + EditViewResizeForm(frm, false); +/* end TRG */ + CurrentRecord = event->data.frmGoto.recordNum; + EditViewInit (frm); + fldP = GetObjectPtr (EditMemoField); + FldSetScrollPosition(fldP, event->data.frmGoto.matchPos); + FldSetSelection(fldP, event->data.frmGoto.matchPos, + event->data.frmGoto.matchPos + event->data.frmGoto.matchLen); + EditViewUpdateScrollBar (); + FrmDrawForm (frm); + FrmSetFocus (frm, FrmGetObjectIndex (frm, EditMemoField)); + handled = true; + } + + + else if (event->eType == frmUpdateEvent) + { + handled = EditViewUpdateDisplay (event->data.frmUpdate.updateCode); + } + + else if (event->eType == fldChangedEvent) + { + frm = FrmGetActiveForm (); + EditViewUpdateScrollBar (); + handled = true; + } + + + else if (event->eType == frmCloseEvent) + { + FormPtr frm; + + frm = FrmGetFormPtr (EditView); + if ( FldGetTextHandle (FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, EditMemoField)))) + EditViewSaveRecord (); // This deletes empty memos. + EditViewExit(); + } + + + else if (event->eType == sclRepeatEvent) + { + EditViewScroll (event->data.sclRepeat.newValue - + event->data.sclRepeat.value, false); + } +/* TRG */ + else if (event->eType == displayExtentChangedEvent) + { + EditViewResizeForm(FrmGetActiveForm(), true); + handled = true; + } +/* end TRG */ + + return (handled); +} + +/* TRG */ +/*********************************************************************** + * + * FUNCTION: EditViewResizeForm + * + * DESCRIPTION: This routine resizes the y extent of the form for + * virtual silk support. + * + * PARAMETERS: frmP - pointer to EditView form + * draw - if we can draw to the form at this time or not. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * DanF 3/04/01 Initial Revision + * + ***********************************************************************/ +static void EditViewResizeForm(FormPtr frmP, Boolean draw) +{ + Coord x, y; + Coord xDiff, yDiff; + RectangleType r; + FieldPtr fldP; + UInt16 tmpPos, tmpStart, tmpEnd; + UInt16 objIdx; + + // this will get the new extent + WinGetDisplayExtent(&x, &y); + + // this will get the old extent + FrmGetFormBounds(frmP, &r); + + xDiff = x - (r.topLeft.x + r.extent.x); + yDiff = y - (r.topLeft.y + r.extent.y); + if ((xDiff == 0) && (yDiff == 0)) + return; + + // resize form + r.extent.x += xDiff; + r.extent.y += yDiff; + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + + // resize field (save and restore insertion state around it) + if (draw) + { + fldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EditMemoField)); + FldGetSelection(fldP, &tmpStart, &tmpEnd); + if (InsPtEnabled() || (tmpStart != tmpEnd)) + tmpPos = FldGetInsPtPosition(fldP); + else + tmpPos = -1; + } + //Adjust Table + PrvResizeObject(frmP, FrmGetObjectIndex(frmP, EditMemoField), xDiff, yDiff, draw); + + // Adjust scrollbar + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, EditMemoScrollBar), xDiff, 0, false); + PrvResizeObject(frmP, FrmGetObjectIndex(frmP, EditMemoScrollBar), 0, yDiff, draw); + + if(xDiff != 0) + { + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, EditCategoryTrigger), xDiff, 0, draw); //do not double draw + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, EditCategoryList), xDiff, 0, draw); //do not double draw + } + + // move done button + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, EditDoneButton), 0, yDiff, draw); + + // move details button + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, EditDetailsButton), 0, yDiff, draw); + + // Adjust GSI + objIdx = PrvFrmGetGSI(frmP); + PrvMoveObject(frmP, objIdx, xDiff, yDiff, draw); + // You need to set the GSI's location as well as it's location on the form + // for everything to work properly. + FrmGetObjectPosition(frmP, objIdx, &x, &y); + GsiSetLocation(x + xDiff, y+yDiff); + + if (draw) + { + if (tmpPos != -1) + { + // restore the selection, this will make sure the cursor is still visible + fldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EditMemoField)); + FldSetInsPtPosition(fldP, tmpPos); + FldSendChangeNotification(fldP); + FldSetSelection(fldP, tmpStart, tmpEnd); + } + FrmDrawForm(frmP); + } +} +/* end TRG */ +#pragma mark ---- +/*********************************************************************** + * + * FUNCTION: ListViewDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 3/29/95 Initial Revision + * kcr 11/7/95 converted to common about box + * jmp 10/02/99 Changed call to DmOpenDatabaseByTypeCreator() to + * MemoGetDatabase(). + * jmp 03/19/00 Fixed bug #23669: Adjust the number of memos currently + * available so that scrollbar will be updated correctly + * after a change in security level. + * + ***********************************************************************/ +static void ListViewDoCommand (UInt16 command) +{ + Boolean wasHiding; + UInt32 currentRecordID; + UInt16 mode; + + + switch (command) + { + case ListOptionsFontsCmd: + ListFont = SelectFont(ListFont); + break; + + case ListRecordBeamCategoryCmd: + MemoSendCategory(MemoDB, CurrentCategory, exgBeamPrefix, NoDataToBeamAlert); + break; + + case ListRecordSendCategoryCmd: + MemoSendCategory(MemoDB, CurrentCategory, exgSendPrefix, NoDataToSendAlert); + break; + + case ListOptionsSecurityCmd: + wasHiding = (PrivateRecordVisualStatus == hidePrivateRecords); + + PrivateRecordVisualStatus = SecSelectViewStatus(); + + if (wasHiding ^ (PrivateRecordVisualStatus == hidePrivateRecords)) //xor on two logical values - mode to open DB has changed + { + // Close the application's data file. + MemoSavePrefs(0); + DmCloseDatabase(MemoDB); + + mode = (PrivateRecordVisualStatus == hidePrivateRecords) ? + dmModeReadWrite : (dmModeReadWrite | dmModeShowSecret); + + MemoGetDatabase(&MemoDB, mode); + ErrFatalDisplayIf(!MemoDB,"Can't reopen DB"); + // Read the preferences. + MemoLoadPrefs(¤tRecordID); + + // Adjust the number of memos currently available so the scrollbar will be updated correctly. + if (ShowAllCategories) + MemosInCategory = DmNumRecordsInCategory(MemoDB, dmAllCategories); + else + MemosInCategory = DmNumRecordsInCategory(MemoDB, CurrentCategory); + } + + //For safety, simply reset the currentRecord + CurrentRecord = noRecordSelected; + ListViewUpdateDisplay(updateDisplayOptsChanged); + break; + + case ListOptionsPreferencesCmd: + FrmPopupForm (PreferencesDialog); + break; + + case ListOptionsAboutCmd: + MenuEraseStatus(CurrentMenu); + AbtShowAbout(sysFileCMemo); + break; + } +} + + +/*********************************************************************** + * + * FUNCTION: ListViewNumberOfRows + * + * DESCRIPTION: This routine return the maximun number of visible rows, + * with the current list view font setting. + * + * PARAMETERS: table - List View table + * + * RETURNED: maximun number of displayable rows + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 8/28/97 Initial Revision + * + ***********************************************************************/ +static UInt16 ListViewNumberOfRows (TablePtr table) +{ + UInt16 rows; + UInt16 rowsInTable; + UInt16 tableHeight; + FontID currFont; + RectangleType r; + + + rowsInTable = TblGetNumberOfRows (table); + + TblGetBounds (table, &r); + tableHeight = r.extent.y; + + currFont = FntSetFont (ListFont); + rows = tableHeight / FntLineHeight (); + FntSetFont (currFont); + + if (rows <= rowsInTable) + return (rows); + else + return (rowsInTable); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewDrawRecord + * + * DESCRIPTION: This routine draws the title memo record in the list + * view. This routine is called by the table routine, + * TblDrawTable, each time a line of the table needs to + * be drawn. + * + * PARAMETERS: table - pointer to the memo list table (TablePtr) + * row - row of the table to draw + * column - column of the table to draw + * bounds - bound to the draw region + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * ADH 7/21/99 Increased the size of the posStr character array + * to allow for display of five digit numbers. + * Previously only four digit numbers could be + * displayed. + * ryw 1/11/01 use global TopRowPositionInCategory to determine numbering + * + ***********************************************************************/ +static void ListViewDrawRecord (void * table, Int16 row, Int16 UNUSED_PARAM(column), + RectanglePtr bounds) +{ + UInt16 len; + UInt16 category; + UInt16 recordNum; + MemHandle memoH; + Int16 x, y; + Char * memoP; + UInt16 pos; + // this string should handle up to "99999." but does not have to be 0 terminated when the . is added + char posStr[6]; + UInt16 attr; + RectangleType maskRectangle; + + // Get the record number that corresponds to the table item to draw. + // The record number is stored in the "intValue" field of the item. + recordNum = TblGetRowID (table, row); + + DmRecordInfo (MemoDB, recordNum, &attr, NULL, NULL); + // If the record is private and we are to hide private records, then get out of here. + // This should be taken care of by the calling function, but we will go ahead and + // take care of it here also. + if ((attr & dmRecAttrSecret) && PrivateRecordVisualStatus == hidePrivateRecords) + { + return; + } + + x = bounds->topLeft.x + 1; + y = bounds->topLeft.y; + + FntSetFont (ListFont); + + // Format the memo's postion, within its category, an draw it. + if (ShowAllCategories) + category = dmAllCategories; + else + category = CurrentCategory; + + //pos = DmPositionInCategory (MemoDB, recordNum, category); + pos = TopRowPositionInCategory + row; + StrIToA (posStr, pos+1); + len = StrLen(posStr); + // Warning if more than 99999 record (5 chars) + ErrNonFatalDisplayIf(len > sizeof(posStr) - 1, "Too many records"); + posStr[len++] = '.'; + // This string does not need 0 termination for up to the end of the function. So the size is ok + + if (len < 3) x += FntCharWidth ('1'); + WinDrawChars (posStr, len, x, y); + x += FntCharsWidth (posStr, len) + 4; + + // If we are here then we either we either mask the memo out or display the + // memo title. + if (((attr & dmRecAttrSecret) && PrivateRecordVisualStatus == maskPrivateRecords)) + { + MemMove (&maskRectangle, bounds, sizeof (RectangleType)); + maskRectangle.topLeft.x = x; + maskRectangle.extent.x = bounds->extent.x - x; + + //If next row is masked, thicken rect so as to keep boundary at 1 pixel. + /* // THIS CODE REMOVED because people didn't like combining the masks together. + if (TblGetLastUsableRow(table) > row) + { + DmRecordInfo (MemoDB, TblGetRowID (table, row+1), &attr, NULL, NULL); + if (attr & dmRecAttrSecret) + maskRectangle.extent.y++; + } + */ + ListViewDisplayMask (&maskRectangle); + } + else + { + // Display the memo's title, the title is the first line of the memo. + memoH = DmQueryRecord(MemoDB, recordNum); + memoP = MemHandleLock(memoH); + DrawMemoTitle (memoP, x, y, bounds->extent.x - x); + MemHandleUnlock(memoH); + } +} + +/*********************************************************************** + * + * FUNCTION: ListViewDisplayMask + * + * DESCRIPTION: Draws the masked display for the record. + * + * PARAMETERS: bounds (Input): The bounds of the table item to display. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * css 06/21/99 Initial Revision + * + ***********************************************************************/ +static void ListViewDisplayMask (RectanglePtr bounds) +{ + RectangleType tempRect; + CustomPatternType origPattern; + MemHandle bitmapH; + BitmapType * bitmapP; + + CustomPatternType pattern = {0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55}; + +MemMove (&tempRect, bounds, sizeof (RectangleType)); +// Make sure it fits nicely into the display. +tempRect.topLeft.y++; +tempRect.extent.y --; +/* TRG */ + if (vgaExists && VgaIsVgaFont(ListFont)) + tempRect.extent.x -= SecLockWidth + ((SecLockWidth+1)>>1) + 1; + else + tempRect.extent.x -= SecLockWidth + 1; +/* end TRG */ + +WinGetPattern(&origPattern); +WinSetPattern (&pattern); +WinFillRectangle (&tempRect, 0); +WinSetPattern(&origPattern); + +//draw lock icon + //draw lock icon +/* TRG */ + if (vgaExists && VgaIsVgaFont(ListFont)) + bitmapH = DmGetResource (bitmapRsc, SecLockBitmap+0x1000); + else + bitmapH = DmGetResource (bitmapRsc, SecLockBitmap); +/* end TRG */ +if (bitmapH) +{ + bitmapP = MemHandleLock (bitmapH); + WinDrawBitmap (bitmapP, tempRect.topLeft.x + tempRect.extent.x + 1, + tempRect.topLeft.y + ((tempRect.extent.y - SecLockHeight) / 2)); + MemPtrUnlock (bitmapP); +} +} + +/*********************************************************************** + * + * FUNCTION: ListViewUpdateScrollers + * + * DESCRIPTION: This routine draws or erases the list view scroll arrow + * buttons. + * + * PARAMETERS: frm - pointer to the to do list form + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/1/95 Initial Revision + * + ***********************************************************************/ +static void ListViewUpdateScrollers (FormPtr UNUSED_PARAM(frm)) +{ + UInt16 pos; + Int16 rows; + UInt16 maxValue; + + rows = ListViewNumberOfRows (GetObjectPtr(ListTable)); + if (MemosInCategory > rows) + { + pos = DmPositionInCategory (MemoDB, TopVisibleRecord, CurrentCategory); + maxValue = MemosInCategory - rows; + } + else + { + pos = 0; + maxValue = 0; + } + + SclSetScrollBar (GetObjectPtr (ListScrollBar), pos, 0, maxValue, rows); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewLoadTable + * + * DESCRIPTION: This routine loads memo database records into + * the list view form. + * + * PARAMETERS: recordNum index of the first record to display. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/16/95 Initial Revision + * grant 1/29/99 Set the heights of unused rows + * ryw 1/11/01 update global TopRowPositionInCategory on table load + * + ***********************************************************************/ +static void ListViewLoadTable (FormPtr frm) +{ + UInt16 row; + UInt16 recordNum; + UInt16 lineHeight; + UInt16 dataHeight; + UInt16 tableHeight; + UInt16 numRows; + UInt32 uniqueID; + FontID currFont; + TablePtr table; + MemHandle recordH; + RectangleType r; + + + table = GetObjectPtr (ListTable); + + TblGetBounds (table, &r); + tableHeight = r.extent.y; + + currFont = FntSetFont (ListFont); + lineHeight = FntLineHeight (); + FntSetFont (currFont); + + dataHeight = 0; + + recordNum = TopVisibleRecord; + + // For each row in the table, store the record number in the table item + // that will dispaly the record. + numRows = TblGetNumberOfRows (table); + for (row = 0; row < numRows; row++) + { + // Get the next record in the currunt category. + recordH = DmQueryNextInCategory (MemoDB, &recordNum, CurrentCategory); + if(row == 0) + { + // store the position of the first row so we can use TopRowPositionInCategory+row + // when drawing + TopRowPositionInCategory = recordH ? DmPositionInCategory(MemoDB, recordNum, CurrentCategory) : 0; + } + + // If the record was found, store the record number in the table item, + // otherwise set the table row unusable. + if (recordH && (tableHeight >= dataHeight + lineHeight)) + { + TblSetRowID (table, row, recordNum); + TblSetItemStyle (table, row, 0, customTableItem); + TblSetItemFont (table, row, 0, ListFont); + + TblSetRowHeight (table, row, lineHeight); + + DmRecordInfo (MemoDB, recordNum, NULL, &uniqueID, NULL); + if ((TblGetRowData (table, row) != uniqueID) || + ( ! TblRowUsable (table, row))) + { + TblSetRowUsable (table, row, true); + + // Store the unique id of the record in the row. + TblSetRowData (table, row, uniqueID); + + // Mark the row invalid so that it will draw when we call the + // draw routine. + TblMarkRowInvalid (table, row); + } + + if (row+1 < numRows) recordNum++; + + dataHeight += lineHeight; + } + else + { + // Set the row height - when scrolling winDown, the heights of the last rows of + // the table are used to determine how far to scroll. As rows are deleted + // from the top of the table, formerly unused rows scroll into view, and the + // height is used before the next call to ListViewLoadTable (which would set + // the height correctly). + TblSetRowHeight (table, row, lineHeight); + + TblSetRowUsable (table, row, false); + } + } + + + // Update the scroll arrows. + ListViewUpdateScrollers (frm); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewLoadRecords + * + * DESCRIPTION: This routine loads memo database records into + * the list view form. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/16/95 Initial Revision + * + ***********************************************************************/ +static void ListViewLoadRecords (FormPtr frm) +{ + TablePtr table; + UInt16 recordNum; + UInt16 rowsInTable; + + if (ShowAllCategories) + CurrentCategory = dmAllCategories; + + table = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, ListTable)); + rowsInTable = ListViewNumberOfRows (table); + + // Is the current record before the first visible record? + if (CurrentRecord != noRecordSelected) + { + if (TopVisibleRecord > CurrentRecord) + TopVisibleRecord = CurrentRecord; + + // Is the current record after the last visible record? + else + { + recordNum = TopVisibleRecord; + DmSeekRecordInCategory (MemoDB, &recordNum, rowsInTable-1, + dmSeekForward, CurrentCategory); + if (recordNum < CurrentRecord) + TopVisibleRecord = CurrentRecord; + } + } + + + // Make sure we show a full display of records. + if (MemosInCategory) + { + recordNum = dmMaxRecordIndex; + DmSeekRecordInCategory (MemoDB, &recordNum, (rowsInTable-1), + dmSeekBackward, CurrentCategory); + TopVisibleRecord = min (TopVisibleRecord, recordNum); + } + else + TopVisibleRecord = 0; + + ListViewLoadTable (frm); + + // Set the callback routine that will draw the records. + TblSetCustomDrawProcedure (table, 0, ListViewDrawRecord); + + TblSetColumnUsable (table, 0, true); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewSelectCategory + * + * DESCRIPTION: This routine handles selection, creation and deletion of + * categories form the Details Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: The index of the new category. + * + * The following global variables are modified: + * CurrentCategory + * ShowAllCategories + * CategoryName + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 03/10/95 Initial Revision + * gap 08/13/99 Update to use new constant categoryDefaultEditCategoryString. + * + ***********************************************************************/ +static UInt16 ListViewSelectCategory (void) +{ + FormPtr frm; + TablePtr table; + UInt16 category; + Boolean categoryEdited; + + + // Process the category popup list. + category = CurrentCategory; + + frm = FrmGetActiveForm(); + categoryEdited = CategorySelect (MemoDB, frm, ListCategoryTrigger, + ListCategoryList, true, &category, CategoryName, 1, categoryDefaultEditCategoryString); + + if (category == dmAllCategories) + ShowAllCategories = true; + else + ShowAllCategories = false; + + if (categoryEdited || (category != CurrentCategory)) + { + ChangeCategory (category); + + // Display the new category. + ListViewLoadRecords (frm); + table = GetObjectPtr (ListTable); + TblEraseTable (table); + TblDrawTable (table); + } + + return (category); +} + +/*********************************************************************** + * + * FUNCTION: ListViewNextCategory + * + * DESCRIPTION: This routine display the next category, if the last + * catagory isn't being displayed + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * The following global variables are modified: + * CurrentCategory + * ShowAllCategories + * CategoryName + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/15/95 Initial Revision + * + ***********************************************************************/ +static void ListViewNextCategory (void) +{ + UInt16 category; + FormPtr frm; + TablePtr table; + ControlPtr ctl; + + category = CategoryGetNext (MemoDB, CurrentCategory); + + if (category != CurrentCategory) + { + if (category == dmAllCategories) + ShowAllCategories = true; + else + ShowAllCategories = false; + + ChangeCategory (category); + + // Set the label of the category trigger. + ctl = GetObjectPtr (ListCategoryTrigger); + CategoryGetName (MemoDB, CurrentCategory, CategoryName); + CategorySetTriggerLabel (ctl, CategoryName); + + + // Display the new category. + TopVisibleRecord = 0; + frm = FrmGetActiveForm (); + ListViewLoadTable (frm); + table = GetObjectPtr (ListTable); + TblEraseTable (table); + TblDrawTable (table); + } +} + + +/*********************************************************************** + * + * FUNCTION: ListViewPageScroll + * + * DESCRIPTION: This routine scrolls the list of of memo titles + * in the direction specified. + * + * PARAMETERS: direction - winUp or dowm + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * roger 7/27/95 Copied fixed code from Address Book + * + ***********************************************************************/ +static void ListViewPageScroll (WinDirectionType direction) +{ + TablePtr table; + Int16 rowsInTable; + UInt16 newTopVisibleRecord; + + table = GetObjectPtr (ListTable); + rowsInTable = ListViewNumberOfRows (table); + + newTopVisibleRecord = TopVisibleRecord; + CurrentRecord = noRecordSelected; + + // Scroll the table winDown a page (less one row). + if (direction == winDown) + { + // Try going forward one page + if (!SeekRecord (&newTopVisibleRecord, rowsInTable - 1, dmSeekForward)) + { + // Try going backwards one page from the last record + newTopVisibleRecord = dmMaxRecordIndex; + if (!SeekRecord (&newTopVisibleRecord, rowsInTable - 1, dmSeekBackward)) + { + // Not enough records to fill one page. Start with the first record + newTopVisibleRecord = 0; + SeekRecord (&newTopVisibleRecord, 0, dmSeekForward); + } + } + } + + // Scroll up a page (less one row). + else + { + if (!SeekRecord (&newTopVisibleRecord, rowsInTable - 1, dmSeekBackward)) + { + // Not enough records to fill one page. Start with the first record + newTopVisibleRecord = 0; + SeekRecord (&newTopVisibleRecord, 0, dmSeekForward); + } + } + + + + // Avoid redraw if no change + if (TopVisibleRecord != newTopVisibleRecord) + { +/* TRG */ + selectedItem = -1; +/* end TRG */ + TopVisibleRecord = newTopVisibleRecord; + ListViewLoadRecords (FrmGetActiveForm ()); + TblRedrawTable(table); + } +} + + + +/*********************************************************************** + * + * FUNCTION: ListViewScroll + * + * DESCRIPTION: This routine scrolls the list of of memo titles + * in the direction specified. + * + * PARAMETERS: direction - winUp or dowm + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * roger 7/27/95 Copied fixed code from Address Book + * + ***********************************************************************/ +static void ListViewScroll (Int16 linesToScroll) +{ + Int16 i; + UInt16 rows; + UInt16 lastRow; + UInt16 scrollAmount; + UInt16 newTopVisibleRecord; + TablePtr table; + RectangleType scrollR; + RectangleType vacated; + WinDirectionType direction; + + + table = GetObjectPtr (ListTable); + CurrentRecord = noRecordSelected; + + + // Find the new top visible record + newTopVisibleRecord = TopVisibleRecord; + + // Scroll down. + if (linesToScroll > 0) + SeekRecord (&newTopVisibleRecord, linesToScroll, dmSeekForward); + + // Scroll up. + else if (linesToScroll < 0) + SeekRecord (&newTopVisibleRecord, -linesToScroll, dmSeekBackward); + + ErrFatalDisplayIf (TopVisibleRecord == newTopVisibleRecord, + "Invalid scroll value"); + + TopVisibleRecord = newTopVisibleRecord; + + + // Move the bits that will remain visible. + rows = ListViewNumberOfRows (table); + if (((linesToScroll > 0) && (linesToScroll < rows)) || + ((linesToScroll < 0) && (-linesToScroll < rows))) + { + scrollAmount = 0; + + if (linesToScroll > 0) + { + lastRow = TblGetLastUsableRow (table) - 1; + for (i = 0; i < linesToScroll; i++) + { + scrollAmount += TblGetRowHeight (table, lastRow); + TblRemoveRow (table, 0); + } + direction = winUp; + } + else + { + for (i = 0; i < -linesToScroll; i++) + { + scrollAmount += TblGetRowHeight (table, 0); + TblInsertRow (table, 0); + } + direction = winDown; + } + + TblGetBounds (table, &scrollR); + WinScrollRectangle (&scrollR, direction, scrollAmount, &vacated); + WinEraseRectangle (&vacated, 0); + } + + + ListViewLoadTable (FrmGetActiveForm ()); + TblRedrawTable(table); +/* TRG */ + if (selectedItem != -1) + ListViewSelectTableItem(true, table, selectedItem, 0, &vacated); +/* end TRG */ +} + + + +/*********************************************************************** + * + * FUNCTION: ListViewInit + * + * DESCRIPTION: This routine initializes the "List View" of the + * Memo application. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: nothing. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * + ***********************************************************************/ +static void ListViewInit (FormPtr frm) +{ + ControlPtr ctl; + +/* TRG */ + selectedItem = -1; +/* end TRG */ + + ListViewLoadRecords (frm); + + // Set the label of the category trigger. + ctl = GetObjectPtr (ListCategoryTrigger); + CategoryGetName (MemoDB, CurrentCategory, CategoryName); + CategorySetTriggerLabel (ctl, CategoryName); + + CurrentView = ListView; +} + + +/*********************************************************************** + * + * FUNCTION: ListViewInvertMoveIndicator + * + * DESCRIPTION: If draw is true, then save the area behind the rectangle, + * then draw the indicator there. If draw is false, then restore + * the screen bits. + * + * + * PARAMETERS: itemR - bounds of the move indicator + * savedBits - if draw is true, then restore this window of bits at + * itemR. + * draw - draw or erase the move indicator. + * + * RETURNED: WinHandle - handle to a saved window of screen bits, if the move + * indicator is visible. Otherwise, the value is 0. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 1/29/96 Initial Revision + * + ***********************************************************************/ +static WinHandle ListViewInvertMoveIndicator (RectanglePtr itemR, WinHandle savedBits, + Boolean draw) +{ + UInt16 i; + UInt16 err; + WinHandle winH = 0; + RectangleType indictatorR; + CustomPatternType pattern; + CustomPatternType savedPattern; + + + indictatorR.topLeft.x = itemR->topLeft.x; + indictatorR.topLeft.y = itemR->topLeft.y + itemR->extent.y - 2; + indictatorR.extent.x = itemR->extent.x; + indictatorR.extent.y = 2; + + if (draw) + { + WinGetPattern (&savedPattern); + + for (i = 0; i < sizeof (CustomPatternType) / sizeof (*pattern); i++) + pattern[i]= 0xAA55; + + WinSetPattern (&pattern); + + winH = WinSaveBits (&indictatorR, &err); + + WinFillRectangle (&indictatorR, 0); + + WinSetPattern (&savedPattern); + } + + else + { + WinRestoreBits (savedBits, indictatorR.topLeft.x, indictatorR.topLeft.y); + } + + return (winH); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewSelectTableItem + * + * DESCRIPTION: This routine either selects or unselects the specified + * table item. + * + * PARAMETERS: selected - specifies whether an item should be selected or + * unselected + * table - pointer to a table object + * row - row of the item (zero based) + * column - column of the item (zero based) + * rP - pointer to a structure that will hold the bound + * of the item + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * jmp 10/29/99 Initial Revision + * jmp 11/12/99 While a table item is "on the move," having it be selected + * can cause the Table code grief. So, instead of using + * the TblSelectItem()/TblUnhighlightSelect() calls, we now + * manually select/unselect the table's row. Before color, + * only WinInvertRectangle() was called, so this is now in line + * again with the way things used to work. Sigh. + * + ***********************************************************************/ + +static void ListViewSelectTableItem (Boolean selected, TablePtr table, Int16 row, Int16 column, RectangleType *r) +{ + // Get the item's rectangle. + // + TblGetItemBounds (table, row, column, r); + + // Set up the drawing state the way we want it. + // + WinPushDrawState(); + WinSetBackColor(UIColorGetTableEntryIndex(UIFieldBackground)); + WinSetForeColor(UIColorGetTableEntryIndex(UIObjectForeground)); + WinSetTextColor(UIColorGetTableEntryIndex(UIObjectForeground)); + + // Erase and (re)draw the item. + // + WinEraseRectangle(r, 0); + ListViewDrawRecord(table, row, column, r); + + // If selected, make it look that way. + // + if (selected) + ReplaceTwoColors (r, 0, + UIObjectForeground, UIFieldBackground, + UIObjectSelectedForeground, UIObjectSelectedFill); + + // Restore the previous drawing state. + // + WinPopDrawState(); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewSelectMemo + * + * DESCRIPTION: This routine tracks a Memo item for either selection + * to go to EditView, or movement in the ListView. + * + * + * PARAMETERS: event + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 1/29/96 Initial Revision + * jmp 10/29/99 Replaced WinInvertRectangle() calls with calls to + * ListViewSelectTableItem() to eliminate general + * color inversion problem. + * peter 4/25/00 Add support for un-masking just the selected record. + * gap 06/06/00 Correct what appears to be a copy/paste error. When + * row < 0, the row was properly incremented but the + * y value of the move indicator was decremented causing the + * tracking line to draw up across the title area of the form. + * + ***********************************************************************/ + +static void ListViewSelectMemo (EventType * event) +{ + Int16 sortOrder; + Int16 row; + Int16 selectedRow; + Int16 column; + UInt16 recordNum; + Int16 selectedRecord; + Coord x, y; + Boolean penDown = true; + Boolean moving = false; + Boolean selected = true; + TablePtr table; + WinHandle savedBits; + RectangleType r; + UInt16 attr; + + sortOrder = MemoGetSortOrder (MemoDB); + + row = event->data.tblSelect.row; + column = event->data.tblSelect.column; + table = event->data.tblSelect.pTable; + + // Highlight the item the pen when winDown on. + selectedRecord = TblGetRowID (table, row); + ListViewSelectTableItem (selected, table, row, column, &r); + + // Trace the pen until it move enough to constitute a move operation or until + // the pen it released. + while (true) + { + PenGetPoint (&x, &y, &penDown); + if (! penDown) break; + + if (! moving) + { + if (sortOrder != soAlphabetic) + { + // Is the pen still within the bounds of the item it went winDown on, + // if not draw the move indicator. + if (! RctPtInRectangle (x, y, &r)) + { + moving = true; + + TblGetItemBounds (table, row, column, &r); + savedBits = ListViewInvertMoveIndicator (&r, 0, true); + } + } + else + selected = RctPtInRectangle (x, y, &r); + } + + else if (! RctPtInRectangle (x, y, &r)) + { + // Above the first item ? + if (row < 0) + { + if (y >= r.topLeft.y) + { + row++; + ListViewInvertMoveIndicator (&r, savedBits, false); + r.topLeft.y += r.extent.y; + savedBits = ListViewInvertMoveIndicator (&r, 0, true); + } + } + + // Move winUp. + else if (y < r.topLeft.y) + { + recordNum = TblGetRowID (table, row); + if (SeekRecord (&recordNum, 1, dmSeekBackward)) + { + ListViewInvertMoveIndicator (&r, savedBits, false); + if (row) + row--; + else + { + ListViewScroll (-1); + if (TblFindRowID (table, selectedRecord, &selectedRow)) + ListViewSelectTableItem (selected, table, selectedRow, column, &r); + } + TblGetItemBounds (table, row, column, &r); + savedBits = ListViewInvertMoveIndicator (&r, 0, true); + } + else if (row == 0) + { + row--; + ListViewInvertMoveIndicator (&r, savedBits, false); + r.topLeft.y -= r.extent.y; + savedBits = ListViewInvertMoveIndicator (&r, 0, true); + } + } + + // Move winDown + else + { + recordNum = TblGetRowID (table, row); + if (SeekRecord (&recordNum, 1, dmSeekForward)) + { + ListViewInvertMoveIndicator (&r, savedBits, false); + if (row < TblGetLastUsableRow (table)) + row++; + else + { + ListViewScroll (1); + if (TblFindRowID (table, selectedRecord, &selectedRow)) + ListViewSelectTableItem (selected, table, selectedRow, column, &r); + } + TblGetItemBounds (table, row, column, &r); + savedBits = ListViewInvertMoveIndicator (&r, 0, true); + } + } + } + } + + + // Turn off the move indicator, if it is on. + if (moving) + { + savedBits = ListViewInvertMoveIndicator (&r, savedBits, false); + } + + // If the highlighted item is visible, unhighlight it. + if (TblFindRowID (table, selectedRecord, &selectedRow)) + ListViewSelectTableItem (false, table, selectedRow, column, &r); + + if (moving) + { + if (row >= 0) + { + recordNum = TblGetRowID (table, row); + if (selectedRecord == recordNum) + return; + + recordNum++; + } + else + { + recordNum = TblGetRowID (table, 0);; + } + + DmMoveRecord (MemoDB, selectedRecord, recordNum); + /* Was + if (selectedRecord < TopVisibleRecord) + TopVisibleRecord--; + CurrentRecord = recordNum; + ListViewLoadTable (FrmGetActiveForm()); + */ + ListViewLoadRecords (FrmGetActiveForm()); + TblRedrawTable (table); + } + + // If we didn't move the item then it's been selected for editing, go to the + // edit view. + else if (sortOrder != soAlphabetic || selected) + { + CurrentRecord = TblGetRowID (event->data.tblSelect.pTable, + event->data.tblSelect.row); + EditScrollPosition = 0; + + // Get the category and secret attribute of the current record. + DmRecordInfo (MemoDB, CurrentRecord, &attr, NULL, NULL); + + // If this is a "private" record, then determine what is to be shown. + if (attr & dmRecAttrSecret) + { + switch (PrivateRecordVisualStatus) + { + case showPrivateRecords: + FrmGotoForm (EditView); + break; + + case maskPrivateRecords: + if (SecVerifyPW (showPrivateRecords) == true) + { + // We only want to unmask this one record, so restore the preference. + PrefSetPreference (prefShowPrivateRecords, maskPrivateRecords); + + FrmGotoForm (EditView); + } + break; + + // This case should never be executed!!!!!!! + case hidePrivateRecords: + default: + break; + } + } + else + { + FrmGotoForm (EditView); + } + } +} + +/*********************************************************************** + * + * FUNCTION: ListViewUpdateDisplay + * + * DESCRIPTION: This routine update the display of the list view + * + * PARAMETERS: updateCode - a code that indicated what changes have been + * made to the view. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/19/95 Initial Revision + * + ***********************************************************************/ +static Boolean ListViewUpdateDisplay (UInt16 updateCode) +{ + TablePtr table; + + if (updateCode & (updateDisplayOptsChanged | updateFontChanged)) + { + if (updateCode & updateDisplayOptsChanged) + TopVisibleRecord = 0; + + ListViewLoadRecords (FrmGetActiveForm()); + table = GetObjectPtr (ListTable); + TblEraseTable (table); + TblDrawTable (table); + + return (true); + } + + return (false); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "List View" + * of the Memo 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. + * + * HISTORY: + * 02/21/95 art Created by Art Lamb. + * 11/22/98 kwk Handle command keys in separate code block so that + * TxtCharIsPrint doesn't get called w/virtual chars. + * 09/25/99 kwk Use TxtGlueUpperChar to capitalize initial char for + * memo that's autocreated by writing a printable char. + * + ***********************************************************************/ +static Boolean ListViewHandleEvent (EventPtr event) +{ + FormPtr frm; + Boolean handled = false; + UInt16 attr; + UInt32 numLibs; + + if (event->eType == keyDownEvent) + { + // Memo button pressed? + if (TxtCharIsHardKey(event->data.keyDown.modifiers, event->data.keyDown.chr)) + { + if (!(event->data.keyDown.modifiers & poweredOnKeyMask)) + ListViewNextCategory (); + handled = true; + } + + else if (EvtKeydownIsVirtual(event)) + { + // Scroll up key presed? + if (event->data.keyDown.chr == vchrPageUp) + { + ListViewPageScroll (winUp); + handled = true; + } + + // Scroll down key presed? + else if (event->data.keyDown.chr == vchrPageDown) + { + ListViewPageScroll (winDown); + handled = true; + } + + // Send Data key presed? + else if (event->data.keyDown.chr == vchrSendData) + { + ListViewDoCommand(ListRecordSendCategoryCmd); + handled = true; + } +/* TRG */ + else if (event->data.keyDown.chr == chrCarriageReturn) + { + if (selectedItem != -1) + { + CurrentRecord = TblGetRowID (GetObjectPtr(ListTable), selectedItem); + EditScrollPosition = 0; + + // Get the category and secret attribute of the current record. + DmRecordInfo (MemoDB, CurrentRecord, &attr, NULL, NULL); + selectedItem = -1; + + // If this is a "private" record, then determine what is to be shown. + if (attr & dmRecAttrSecret) + { + switch (PrivateRecordVisualStatus) + { + case showPrivateRecords: + FrmGotoForm (EditView); + break; + + case maskPrivateRecords: + if (SecVerifyPW (showPrivateRecords) == true) + { + PrivateRecordVisualStatus = showPrivateRecords; + FrmGotoForm (EditView); + } + break; + + // This case should never be executed!!!!!!! + case hidePrivateRecords: + default: + break; + } + } + else + { + FrmGotoForm (EditView); + } + } + handled = true; + } + else if (event->data.keyDown.chr == vchrNextField) + { + TablePtr tblP; + RectangleType r; + Int16 pos; + + if (DmNumRecordsInCategory(MemoDB, CurrentCategory) == 0) + return true; + + tblP = (TablePtr)GetObjectPtr(ListTable); + + if (selectedItem == TblGetLastUsableRow(tblP)) + { + ListViewSelectTableItem(false, tblP, selectedItem, 0, &r); + pos = DmPositionInCategory (MemoDB, TopVisibleRecord, CurrentCategory); + if ((TblGetLastUsableRow(tblP) + pos+1) < MemosInCategory) + ListViewScroll(1); + } + else if (selectedItem > TblGetLastUsableRow(tblP)) // can happen with silk/font changes + selectedItem = TblGetLastUsableRow(tblP); + else if (selectedItem != -1) + ListViewSelectTableItem(false, tblP, selectedItem, 0, &r); + + if (selectedItem < TblGetLastUsableRow(tblP)) + selectedItem++; + if (selectedItem != -1) + { + ListViewSelectTableItem(true, tblP, selectedItem, 0, &r); + handled = true; + } + } + else if (event->data.keyDown.chr == vchrPrevField) + { + TablePtr tblP; + RectangleType r; + Int16 pos; + + if (DmNumRecordsInCategory(MemoDB, CurrentCategory) == 0) + return true; + + tblP = (TablePtr)GetObjectPtr(ListTable); + + if (selectedItem == 0) + { + ListViewSelectTableItem(false, tblP, selectedItem, 0, &r); + pos = DmPositionInCategory (MemoDB, TopVisibleRecord, CurrentCategory); + if (pos != 0) + ListViewScroll(-1); + } + else if (selectedItem > TblGetLastUsableRow(tblP)) // can happen with silk/font changes + selectedItem = -1; + else if (selectedItem != -1) + ListViewSelectTableItem(false, tblP, selectedItem, 0, &r); + + if ((selectedItem == -1) && (MemosInCategory > 0)) + selectedItem = 0; + + if (selectedItem > 0) + selectedItem--; + + if (selectedItem != -1) + { + ListViewSelectTableItem(true, tblP, selectedItem, 0, &r); + handled = true; + } + } + } +/* end TRG */ + // If printable character, create a new record. + else if (TxtCharIsPrint (event->data.keyDown.chr)) + { + if (CreateRecord ()) + { + FrmGotoForm (EditView); + + event->data.keyDown.chr = TxtGlueUpperChar(event->data.keyDown.chr); + EvtAddEventToQueue (event); + } + + handled = true; + } + } + + + else if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case ListNewButton: + if (CreateRecord ()) + FrmGotoForm (EditView); + handled = true; + break; + + case ListCategoryTrigger: + ListViewSelectCategory (); + handled = true; + break; + } + } + + + else if (event->eType == tblEnterEvent) + { + ListViewSelectMemo (event); + handled = true; + } + + + else if (event->eType == tblSelectEvent) + { + // An item in the list of memos was selected, display it. + CurrentRecord = TblGetRowID (event->data.tblSelect.pTable, + event->data.tblSelect.row); + EditScrollPosition = 0; + + // Get the category and secret attribute of the current record. + DmRecordInfo (MemoDB, CurrentRecord, &attr, NULL, NULL); + + // If this is a "private" record, then determine what is to be shown. + if (attr & dmRecAttrSecret) + { + switch (PrivateRecordVisualStatus) + { + case showPrivateRecords: + FrmGotoForm (EditView); + break; + + case maskPrivateRecords: + // FrmGotoForm (); TODO XXXX + break; + + // This case should never be executed!!!!!!! + case hidePrivateRecords: + default: + break; + } + } + else + { + FrmGotoForm (EditView); + } + + handled = true; + } + + + else if (event->eType == menuOpenEvent) + { + if (ExgGetRegisteredApplications(NULL, &numLibs, NULL, NULL, exgRegSchemeID, exgSendScheme) || !numLibs) + MenuHideItem(ListRecordSendCategoryCmd); + else + MenuShowItem(ListRecordSendCategoryCmd); + // don't set handled = true + } + + else if (event->eType == menuEvent) + { + ListViewDoCommand (event->data.menu.itemID); + return (true); + } + + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); +/* TRG */ + if (vgaExists) + { + VgaFormModify(frm, vgaFormModify160To240); + VgaTableUseBaseFont(FrmGetObjectPtr(frm, FrmGetObjectIndex(frm, ListTable)), + !VgaIsVgaFont(ListFont)); + } + ListViewResizeForm(frm, false); +/* end TRG */ + ListViewInit (frm); + FrmDrawForm (frm); + handled = true; + } + + else if (event->eType == menuCmdBarOpenEvent) + { + MenuCmdBarAddButton(menuCmdBarOnLeft, BarSecureBitmap, menuCmdBarResultMenuItem, ListOptionsSecurityCmd, 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. + } + + else if (event->eType == frmUpdateEvent) + { + handled = ListViewUpdateDisplay (event->data.frmUpdate.updateCode); + } + + else if (event->eType == sclRepeatEvent) + { + ListViewScroll (event->data.sclRepeat.newValue - + event->data.sclRepeat.value); + } +/* TRG */ + else if (event->eType == displayExtentChangedEvent) + { + ListViewResizeForm(FrmGetActiveForm(), true); + handled = true; + } +/* end TRG */ + + return (handled); +} + +/* TRG */ +/*********************************************************************** + * + * FUNCTION: ListViewResizeForm + * + * DESCRIPTION: This routine resizes the y extent of the form for + * virtual silk support. + * + * PARAMETERS: frmP - pointer to ListView form + * draw - if we can draw to the form at this time or not. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * DanF 3/04/01 Initial Revision + * + ***********************************************************************/ +static void ListViewResizeForm(FormPtr frmP, Boolean draw) +{ + Coord x, y; + Coord xDiff, yDiff; + RectangleType r, tableR; + TablePtr tblP; + + // this will get the new extent + WinGetDisplayExtent(&x, &y); + + // this will get the old extent + FrmGetFormBounds(frmP, &r); + + xDiff = x - (r.topLeft.x + r.extent.x); + yDiff = y - (r.topLeft.y + r.extent.y); + if ((xDiff==0) && (yDiff == 0)) + return; + + // resize form + r.extent.x += xDiff; + r.extent.y += yDiff; + if ((xDiff > 0) || (yDiff > 0)) // only resize here if growing + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + + // adjust table + //PrvResizeObject(frmP, FrmGetObjectIndex(frmP, ListTable), xDiff, yDiff, draw); + tblP = GetObjectPtr(ListTable); + TblGetBounds(tblP, &tableR); + tableR.extent.x += xDiff; + tableR.extent.y += yDiff; + TblSetBounds(tblP, &tableR); + + if(draw && (yDiff < 0)) + { + tableR.topLeft.y = (tableR.topLeft.y + tableR.extent.y); + tableR.extent.y = -yDiff; + WinEraseRectangle (&tableR, 0); + } + + //Only one column so do it here. + if(xDiff != 0) + { + x = TblGetColumnWidth (FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ListTable)), 0); + TblSetColumnWidth (FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ListTable)), 0, x + xDiff); + } + + // adjust scrollbar + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, ListScrollBar), xDiff, 0, false); //do not double draw + PrvResizeObject(frmP, FrmGetObjectIndex(frmP, ListScrollBar), 0, yDiff, draw); + + if(xDiff != 0) + { + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, ListCategoryTrigger), xDiff, 0, draw); //do not double draw + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, ListCategoryList), xDiff, 0, draw); //do not double draw + } + + // move new button + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, ListNewButton), 0, yDiff, draw); + + // don't resize form until here if shrinking so we can erase our old controls + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + + if (draw) + { + // ListViewLoadRecords() can scroll the table. We need to make sure + // we are still selecting the same item after we are all done, so save + // the current state. + if (selectedItem != -1) + selectedItem += TopVisibleRecord; + ListViewLoadRecords(frmP); + FrmDrawForm(frmP); + + if (selectedItem != -1) + { + selectedItem -= TopVisibleRecord; + tblP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, ListTable)); + if (selectedItem > TblGetLastUsableRow(tblP)) + { + ListViewScroll(selectedItem - TblGetLastUsableRow(tblP)); + selectedItem -= selectedItem - TblGetLastUsableRow(tblP); + } + ListViewSelectTableItem(true, tblP, selectedItem, 0, &r); + } + } +} +/* end TRG */ + + +#pragma mark ---- +/*********************************************************************** + * + * FUNCTION: CustomAcceptBeamDialog + * + * DESCRIPTION: This routine uses uses a new exchange manager function to + * Ask the user if they want to accept the data as well as set + * the category to put the data in. By default all data will go + * to the unfiled category, but the user can select another one. + * We store the selected category index in the appData field of + * the exchange socket so we have it at the when we get the receive + * data launch code later. + * + * PARAMETERS: dbP - open database that holds category information + * askInfoP - structure passed on exchange ask launchcode + * + * RETURNED: Error if any + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * bhall 9/7/99 Initial Revision + * gavin 11/9/99 Rewritten to use new ExgDoDialog function + * + ***********************************************************************/ +static Err CustomAcceptBeamDialog(DmOpenRef dbP, ExgAskParamPtr askInfoP) +{ + ExgDialogInfoType exgInfo; + Err err; + Boolean result; + + // set default category to unfiled + exgInfo.categoryIndex = dmUnfiledCategory; + // Store the database ref into a gadget for use by the event handler + exgInfo.db = dbP; + + // Let the exchange manager run the dialog for us + result = ExgDoDialog(askInfoP->socketP, &exgInfo, &err); + + + if (!err && result) { + + // pretend as if user hit OK, we'll now accept the data + askInfoP->result = exgAskOk; + + // Stuff the category index into the appData field + askInfoP->socketP->appData = exgInfo.categoryIndex; + } else { + // pretend as if user hit cancel, we won't accept the data + askInfoP->result = exgAskCancel; + } + + return err; +} + + + +/*********************************************************************** + * + * FUNCTION: ApplicationHandleEvent + * + * DESCRIPTION: This routine loads form resources and sets the event + * handler for the form loaded. + * + * 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. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/11/95 Initial Revision + * + ***********************************************************************/ +static Boolean ApplicationHandleEvent (EventType * event) +{ + UInt16 formID; + FormPtr frm; + + if (event->eType == frmLoadEvent) + { + // Load the form resource. + formID = event->data.frmLoad.formID; + frm = FrmInitForm (formID); + FrmSetActiveForm (frm); + + // Set the event handler for the form. The handler of the currently + // active form is called by FrmHandleEvent each time it receives an + // event. + switch (formID) + { + case ListView: + FrmSetEventHandler (frm, ListViewHandleEvent); + break; + + case EditView: + FrmSetEventHandler (frm, EditViewHandleEvent); + break; + + case DetailsDialog: + FrmSetEventHandler (frm, DetailsHandleEvent); + break; + + case PreferencesDialog: + FrmSetEventHandler (frm, PreferencesHandleEvent); + break; + + } + return (true); + } + return (false); +} + + +/*********************************************************************** + * + * FUNCTION: EventLoop + * + * DESCRIPTION: This routine is the event loop for the Memo + * aplication. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * + ***********************************************************************/ +static void EventLoop (void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent (&event, evtWaitForever); + + if (! SysHandleEvent (&event)) + + if (! MenuHandleEvent (CurrentMenu, &event, &error)) + + if (! ApplicationHandleEvent (&event)) + + FrmDispatchEvent (&event); + + } + while (event.eType != appStopEvent); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the Memo + * application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * art 1/3098 Removed sysAppLaunchCmdSaveData logic + * grant 6/25/99 In sysAppLaunchCmdInitDatabase, set the backup bit on the DB. + * In sysAppLaunchCmdExgReceiveData, update MemosInCategory. + * jmp 10/02/99 Made the support for the sysAppLaunchCmdExgReceiveData + * sysAppLaunchCmdExgAskUser launch codes more like their + * counterparts in Address, Databook, and ToDo. + * jmp 10/18/99 If the default "demo" database image doesn't exist, then + * create an empty database instead. + * jmp 11/04/99 Eliminate extraneous FrmSaveAllForms() call from sysAppLaunchCmdExgAskUser + * since it was already being done in sysAppLaunchCmdExgReceiveData if + * the user affirmed sysAppLaunchCmdExgAskUser. Also, in sysAppLaunchCmdExgReceiveData + * prevent call FrmSaveAllForms() if we're being call back through + * PhoneNumberLookup() as the two tasks are incompatible with each other. + * + ***********************************************************************/ +UInt32 PilotMain (UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + UInt16 error; + DmOpenRef dbP; + + if (cmd == sysAppLaunchCmdNormalLaunch) + { + error = StartApplication (); + if (error) + return (error); + + FrmGotoForm (CurrentView); + EventLoop (); + StopApplication (); + } + + else if (cmd == sysAppLaunchCmdFind) + { + Search ((FindParamsPtr)cmdPBP); + } + + + // This action code might be sent to the app when it's already running + // if the use hits the Find soft key next to the Graffiti area. + else if (cmd == sysAppLaunchCmdGoTo) + { + if (launchFlags & sysAppLaunchFlagNewGlobals) + { + error = StartApplication (); + if (error) return (error); + + GoToItem ((GoToParamsPtr) cmdPBP, true); + + EventLoop (); + StopApplication (); + } + else + GoToItem ((GoToParamsPtr) cmdPBP, false); + } + + + // Launch code sent to running app before sysAppLaunchCmdFind + // or other action codes that will cause data searches or manipulation. + // We don't need to respond to this launch code because memos are + // edited in place. + // else if (cmd == sysAppLaunchCmdSaveData) + // { + // FrmSaveAllForms (); + // } + + + // This launch code is sent after the system is reset. We use this time + // to create our default database. If there is no default database image, + // then we create an empty database. + else if (cmd == sysAppLaunchCmdSystemReset) + { + if (((SysAppLaunchCmdSystemResetType*)cmdPBP)->createDefaultDB) + { + error = CreateDefaultDatabase(); + // Register to receive .txt and text/plain on hard reset. + RegisterData(); + + } + RegisterLocaleChangingNotification(); + } + + + else if (cmd == sysAppLaunchCmdSyncNotify) + { + SyncNotification (); + } + + + else if (cmd == sysAppLaunchCmdExgAskUser) + { + // if our app is not active, we need to open the database + // the subcall flag is used here since this call can be made without launching the app + if (!(launchFlags & sysAppLaunchFlagSubCall)) + { + error = MemoGetDatabase (&dbP, dmModeReadWrite); + } + else + dbP = MemoDB; + + if (dbP != NULL) + { + CustomAcceptBeamDialog (dbP, (ExgAskParamPtr) cmdPBP); + + if (!(launchFlags & sysAppLaunchFlagSubCall)) + error = DmCloseDatabase(dbP); + } + } + + + // Present the user with ui to perform a lookup and return a string + // with information from the selected record. + else if (cmd == sysAppLaunchCmdExgReceiveData) + { + UInt16 numReceived = 0; + UInt32 currentUID; + + // if our app is not active, we need to open the database + // the subcall flag is used here since this call can be made without launching the app + if (!(launchFlags & sysAppLaunchFlagSubCall)) + error = MemoGetDatabase (&dbP, dmModeReadWrite); + else + { + dbP = MemoDB; + + // We don't delete the current record if it's empty because the user + // could cancel the beam receive. + + // MemoReceiveData() calls MemoSort(), which may change the index of + // the current record. So we remember its UID here, and refresh our + // copy of its index afterwards. + if (CurrentRecord != noRecordSelected) + DmRecordInfo(dbP, CurrentRecord, NULL, ¤tUID, NULL); + } + + if (dbP != NULL) + { + error = MemoReceiveData(dbP, (ExgSocketPtr) cmdPBP, &numReceived); + + // We may have just added some memos to the current category. + // If the app is currently running, update MemosInCategory to reflect this. + if (launchFlags & sysAppLaunchFlagSubCall) + { + MemosInCategory += numReceived; + + if (CurrentRecord != noRecordSelected) + { + if (DmFindRecordByID(dbP, currentUID, &CurrentRecord) != 0) + CurrentRecord = noRecordSelected; // Can't happen, but... + + // DOLATER dje - + // To fix the off-by-one error, we can decrement exgSocketP->goToParams.recordNum + // if it's after the current empty record in order to compensate for the + // current empty record getting deleted when we exit before the goto launch. + } + } + else + DmCloseDatabase(dbP); + } + else + error = exgErrAppError; // DOLATER dje - use a new error code - "try again after switching apps" + + // If we can't open our database, return the error since it wasn't passed to ExgDisconnect + return error; + } + + else if(cmd == sysAppLaunchCmdExgPreview) + { + MemoTransferPreview((ExgPreviewInfoType *)cmdPBP); + } + + // This action code is sent by the DesktopLink server when it create + // a new database. We will initializes the new database. + else if (cmd == sysAppLaunchCmdInitDatabase) + { + MemoAppInfoInit (((SysAppLaunchCmdInitDatabaseType*)cmdPBP)->dbP); + + // Set the backup bit. This is to aid syncs with non Palm software. + SetDBBackupBit(((SysAppLaunchCmdInitDatabaseType*)cmdPBP)->dbP); + } + + else if (cmd == sysAppLaunchCmdNotify) + { + if (((SysNotifyParamType*)cmdPBP)->notifyType == sysNotifyLocaleChangedEvent) + { + DmSearchStateType searchState; + LocalID dbID; + UInt16 cardNo; + + // Since the locale has changed, delete the existing database + // and re-create it for the new locale + error = DmGetNextDatabaseByTypeCreator (true, &searchState, memoDBType, + sysFileCMemo, true, &cardNo, &dbID); + if (!error) + DmDeleteDatabase(cardNo, dbID); + + error = CreateDefaultDatabase(); + + } + } + + return (errNone); +} diff --git a/handera-sdk-105/examples/ExampleI/Src/MemoMain.h b/handera-sdk-105/examples/ExampleI/Src/MemoMain.h new file mode 100644 index 0000000..ab61a71 --- /dev/null +++ b/handera-sdk-105/examples/ExampleI/Src/MemoMain.h @@ -0,0 +1,66 @@ +/****************************************************************************** + * + * Copyright (c) 1995-2000 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MemoMain.h + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * Include file the Memo application + * + * History: + * 9/27/95 Created by Christopher Raff + * 10/02/99 Externed the SetDBBackupBit() routine. + * + *****************************************************************************/ + +#ifndef __MEMOMAIN_H__ +#define __MEMOMAIN_H__ + +#include +#include + +#define memoDBName "MemoDB" +#define memoDBType 'DATA' +#define memoMaxLength 4096 // note: must be same as tFLD 1109 max length!!! + // dje - Was 8192. Changed to fix bug #24574. +#define memoExtension "txt" +#define memoMIMEType "text/plain" + + +/************************************************************ + * Function Prototypes + *************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + + +typedef UInt32 ReadFunctionF (const void * stream, Char * bufferP, UInt32 length); +typedef UInt32 WriteFunctionF (void * stream, const Char * const bufferP, Int32 length); + + +// From MemoTransfer.c +extern void MemoSendRecord (DmOpenRef dbP, Int16 recordNum, const Char * const prefix); + +extern void MemoSendCategory (DmOpenRef dbP, UInt16 categoryNum, const Char * const prefix, UInt16 noDataAlertID); + +extern Err MemoReceiveData(DmOpenRef dbP, ExgSocketPtr exgSocketP, UInt16 *numRecordsReceived); +extern void MemoTransferPreview(ExgPreviewInfoType *infoP); + +extern Boolean MemoImportMime(DmOpenRef dbR, void * inputStream, ReadFunctionF inputFunc, + Boolean obeyUniqueIDs, Boolean beginAlreadyRead, UInt16 *numRecordsReceivedP, Char* descriptionP, UInt16 descriptionSize); + +extern void MemoExportMime(DmOpenRef dbP, Int16 index, MemoDBRecordType *recordP, + void * outputStream, WriteFunctionF outputFunc, + Boolean writeUniqueIDs, Boolean outputMimeInfo); + +extern void SetDBBackupBit(DmOpenRef dbP); + +#ifdef __cplusplus +} +#endif + +#endif // __MEMOMAIN_H__ diff --git a/handera-sdk-105/examples/ExampleI/Src/MemoRsc.h b/handera-sdk-105/examples/ExampleI/Src/MemoRsc.h new file mode 100644 index 0000000..4951cfe --- /dev/null +++ b/handera-sdk-105/examples/ExampleI/Src/MemoRsc.h @@ -0,0 +1,101 @@ +/****************************************************************************** + * + * Copyright (c) 1999-2000 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MemoRsc.h + * + * Release: Palm OS SDK 4.0 (63220) + * + *****************************************************************************/ + +// List View +#define ListView 1000 +#define ListCategoryTrigger 1003 +#define ListCategoryList 1004 +#define ListNewButton 1005 +#define ListTable 1008 +#define ListScrollBar 1009 + +// Edit View +#define EditView 1100 +#define EditViewTitle 1101 +#define EditCategoryTrigger 1103 +#define EditCategoryList 1104 +#define EditDoneButton 1105 +#define EditDetailsButton 1108 +#define EditMemoField 1109 +#define EditMemoScrollBar 1110 +#define EditTitleString 1112 +#define EditFontGroup 1 + +// Details Dialog Box +#define DetailsDialog 1200 +#define DetailsCategoryTrigger 1204 +#define DetailsCategoryList 1205 +#define DetailsSecretCheckbox 1207 +#define DetailsOkButton 1208 +#define DetailsCancelButton 1209 +#define DetailsDeleteButton 1210 +#define DetailsHelpString 1211 + +// Options Dialog +#define PreferencesDialog 1400 +#define PreferencesSortByTrigger 1404 +#define PreferencesSortByList 1405 +#define PreferencesOkButton 1406 +#define PreferencesCancelButton 1407 +#define PreferencesFontGroup 1 + +// Delete Memo Dialog +#define DeleteMemoDialog 1600 +#define DeleteMemoSaveBackup 1604 +#define DeleteMemoOk 1606 +#define DeleteMemoCancel 1607 + +// Sort Memo Alert +#define alphabeticSortAlert 2000 +#define alphabeticSortYes 0 +#define alphabeticSortNo 1 + +// Menus +#define ListViewMenuBar 1000 + +#define EditViewMenuBar 1100 + +// List View Menu commands +#define ListRecordBeamCategoryCmd 100 +#define ListRecordSendCategoryCmd 101 +#define ListOptionsFontsCmd 200 +#define ListOptionsPreferencesCmd 201 +#define ListOptionsSecurityCmd 202 +#define ListOptionsAboutCmd 203 + +// Edit View Menu commands +#define NewMemoCmd 100 +#define DeleteMemoCmd 101 +#define BeamMemoCmd 103 +#define SendMemoCmd 104 + +#define UndoCmd 200 +#define CutCmd 201 +#define CopyCmd 202 +#define PasteCmd 203 +#define SelectAllCmd 204 +#define EditSeparator 205 +#define KeyboardCmd 206 + +#define EditOptionsFontsCmd 300 +#define EditOptionPhoneLookupCmd 301 +#define EditOptionsAboutCmd 302 + +//Command bars +#define EditMenuCtl 100 // hasCCP, has extras +#define ListMenuCtl 200 // don't use MenuCtlxxxButtonIndex defaults +#define ListMenuCtlSecure 0 + +// Strings +#define FindMemoHeaderStr 100 +#define BeamDescriptionStr 1000 +#define BeamFilenameStr 1001 +#define ExgDescriptionStr 1002 diff --git a/handera-sdk-105/examples/ExampleI/Src/MemoTransfer.c b/handera-sdk-105/examples/ExampleI/Src/MemoTransfer.c new file mode 100644 index 0000000..0fba172 --- /dev/null +++ b/handera-sdk-105/examples/ExampleI/Src/MemoTransfer.c @@ -0,0 +1,1521 @@ +/****************************************************************************** + * + * Copyright (c) 1997-2000 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MemoTransfer.c + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * Memo Book routines to transfer records. + * + * History: + * 9/17/97 roger - Created + * + *****************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "MemoDB.h" +#include "MemoMain.h" +#include "MemoRsc.h" + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define identifierLengthMax 40 +#define mimeVersionString "MIME-Version: 1.0\015\012" +#define mimeMultipartString "Content-type: multipart/mixed;" +#define mimeBoundaryString "boundary=" +#define memoSuffix ("." memoExtension) +#define simpleBoundary "simple boundary" +#define delimiter "--" simpleBoundary +#define crlf "\015\012" + +#define importBufferMaxLength 80 + +#define stringZLen -1 // pass to WriteFunc to calculate strlen + + +// Stream interface to exgsockets to optimize performance +#define maxStreamBuf 512 // MUST BE LARGER than importBufferMaxLength + +typedef struct StreamType { + ExgSocketPtr socket; + UInt16 pos; + UInt16 len; + UInt16 bufSize; + Char buf[maxStreamBuf]; +} StreamType; + + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ +static void PrvMemoImportMimeCleanup(DmOpenRef dbP, UInt32 firstRecordID, void* inputStream, UInt16 numRecordsReceived, UInt16* numRecordsReceivedP); +static void PrvStreamInit(StreamType *streamP, ExgSocketPtr exgSocketP); +static void PrvStreamFlush(StreamType *streamP); +static UInt32 PrvStreamWrite(StreamType *streamP, const Char * stringP, Int32 length, Err *errP); +static UInt32 PrvStreamRead(StreamType * streamP, Char *bufP, UInt32 length, Err *errP); +static ExgSocketPtr PrvStreamSocket(StreamType *streamP); +static UInt32 PrvReadFunction(const void * stream, Char * bufferP, UInt32 length); +static UInt32 PrvWriteFunction(void * stream, const Char * const bufferP, Int32 length); +static void PrvTransferCleanFileName(Char* ioFileName); +static void PrvSetDescriptionAndFilename(Char * textP, Char **descriptionPP, MemHandle *descriptionHP, Char **filenamePP, MemHandle *filenameHP, const Char * const prefix); +static Err PrvMemoSendRecordTryCatch (DmOpenRef dbP, Int16 recordNum, MemoDBRecordPtr recordP, ExgSocketPtr exgSocketP); +static Err PrvMemoSendCategoryTryCatch (DmOpenRef dbP, UInt16 categoryNum, ExgSocketPtr exgSocketP, UInt16 index); +static void PrvMemoSetGoToParams (DmOpenRef dbP, ExgSocketPtr exgSocketP, UInt32 uniqueID); +static Err PrvReadThroughCRLF(ReadFunctionF inputFunc, void * inputStreamP, Char * bufferP, UInt16 * bufferLengthP); +static void PrvMemoImportFinishRecord(DmOpenRef dbP, UInt16 indexNew, MemHandle *newRecordHPtr, UInt16 *newRecordSizePtr, void * inputStream); + +/************************************************************ + * + * FUNCTION: MemoImportMime + * + * DESCRIPTION: Import a Mime record. + * + * PARAMETERS: + * dbP - pointer to the database to add the record to + * inputStream - pointer to where to import the record from + * inputFunc - function to get input from the stream + * obeyUniqueIDs - true to obey any unique ids if possible + * beginAlreadyRead - whether the begin statement has been read + * numRecordsRecievedP - number of records received + * + * RETURNS: true if the input was read + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * rsf 4/24/97 Initial Revision + * bob 01/26/98 re-wrote MIME parser part to get delimiters right + * grant 6/25/99 Return count of records received in numRecordsReceivedP. + * kwk 06/25/99 Moved return out of ErrTry block. + * FPa 11/22/00 Fixed ErrTry/Catch/Throw problems + * + *************************************************************/ +extern Boolean +MemoImportMime(DmOpenRef dbR, void * inputStream, ReadFunctionF inputFunc, + Boolean UNUSED_PARAM(obeyUniqueIDs), Boolean UNUSED_PARAM(beginAlreadyRead), UInt16 *numRecordsReceivedP, Char* descriptionP, UInt16 descriptionSize) +{ + char *c; + char boundaryString[69+2] = ""; + MemHandle newRecordH = NULL; + Char * newRecordP; + MemHandle newHandle; // Used to follow resized records which move + UInt16 indexNew = dmMaxRecordIndex; + DmOpenRef dbP = dbR; + Err err = 0; + Char buffer[importBufferMaxLength + 1]; + UInt16 bufferLength = 0; + UInt16 charsRead; + UInt16 charsToWrite; + UInt16 newRecordSize = 0; + Char * nextCrChr; + int addCr; + Char * boundaryP; + Char * boundaryEndP; + UInt16 numRecordsReceived = 0; + UInt32 firstRecordID = 0; + + // Keep the buffer always null terminated so we can use string functions on it. + buffer[importBufferMaxLength] = nullChr; + + // Read chars into the buffer + charsRead = inputFunc( inputStream, buffer, importBufferMaxLength - bufferLength); + bufferLength += charsRead; + buffer[bufferLength] = nullChr; + + if (charsRead == 0) + { + *numRecordsReceivedP = 0; + return false; + } + + // An error happens usually due to no memory. It's easier just to + // catch the error. If an error happens, we remove the last record. + // Then we throw a second time so the caller receives it and displays a message. + ErrTry + { + // MIME start, find MIME ID and version + if (StrNCompare(buffer, mimeVersionString, StrLen(mimeVersionString)) == 0) + { + // Remove the MIME header + MemMove(buffer, &buffer[StrLen(mimeVersionString)], bufferLength - StrLen(mimeVersionString)); + bufferLength -= StrLen(mimeVersionString); + + // Read chars into the buffer + charsRead = inputFunc( inputStream, &buffer[bufferLength], importBufferMaxLength - bufferLength); + bufferLength += charsRead; + buffer[bufferLength] = nullChr; + + // scan header for a multi-part identifier + // skip anything else until we get an entirely blank line + do { + if (StrNCompare(buffer, mimeMultipartString, StrLen(mimeMultipartString)) == 0) + { + // found a multi-part header, parse out the boundary string + + // PREVIEW Aba: Here we know that the memo is multipart => several memos + if (descriptionP) + { + MemHandle headerStringH; + Char* headerStringP; + + headerStringH = DmGetResource(strRsc, FindMemoHeaderStr); + headerStringP = MemHandleLock(headerStringH); + StrCopy(descriptionP, headerStringP); + MemHandleUnlock(headerStringH); + DmReleaseResource(headerStringH); + + return true; + } + + boundaryP = StrStr(buffer, mimeBoundaryString); + boundaryP += StrLen(mimeBoundaryString); + + // Remove the boundary stuff so we can read in more into the buffer + MemMove(buffer, boundaryP, &buffer[bufferLength] - boundaryP); + bufferLength = (&buffer[bufferLength] - boundaryP); + + // Read chars into the buffer + charsRead = inputFunc( inputStream, &buffer[bufferLength], importBufferMaxLength - bufferLength); + bufferLength += charsRead; + buffer[bufferLength] = nullChr; + + boundaryP = buffer; + if (*boundaryP == '"') + { + boundaryP++; + boundaryEndP = StrChr(boundaryP, '"'); + } + else + { + boundaryEndP = StrChr(boundaryP, crChr); + } + if (boundaryEndP == NULL) + { + ErrThrow(exgErrBadData); + } + boundaryString[0] = '-'; + boundaryString[1] = '-'; + MemMove(&boundaryString[2], boundaryP, boundaryEndP - boundaryP); + boundaryString[boundaryEndP - boundaryP + 2] = nullChr; + + c = StrChr(boundaryEndP, crChr); + if (c == NULL) + { + ErrThrow(exgErrBadData); + } + c += sizeOf7BitChar(crChr) + sizeOf7BitChar(linefeedChr); + + // Remove the boundary stuff so we can read in more into the buffer + MemMove(buffer, c, &buffer[bufferLength] - c); + bufferLength = (&buffer[bufferLength] - c); + } + else + { + // just an ordinary header line, skip it + err = PrvReadThroughCRLF(inputFunc, inputStream, buffer, &bufferLength); + if (err) + ErrThrow(err); + } + + // Read chars into the buffer + charsRead = inputFunc( inputStream, &buffer[bufferLength], importBufferMaxLength - bufferLength); + bufferLength += charsRead; + buffer[bufferLength] = nullChr; + + // stop at blank line by itself or EOF + } while (buffer[0] != crChr && buffer[0] != nullChr); + + // We've now parsed the MIME header. Preamble, segments, and postamble below. + } // end of MIME parser + + do { + // find the boundary and remove it, along with any header info in the body part + if (*boundaryString != nullChr) + { + // Keep reading until we find a boundary + while (buffer[0] != nullChr && StrNCompare(buffer, boundaryString, StrLen(boundaryString)) != 0) + { + err = PrvReadThroughCRLF(inputFunc, inputStream, buffer, &bufferLength); + if (err) + ErrThrow(err); + } + + // Remove the boundary by removing all text until the end of the line. + err = PrvReadThroughCRLF(inputFunc, inputStream, buffer, &bufferLength); + if (err) + ErrThrow(err); + + while (buffer[0] != nullChr && buffer[0] != crChr) + { + err = PrvReadThroughCRLF(inputFunc, inputStream, buffer, &bufferLength); + if (err) + ErrThrow(err); + } + err = PrvReadThroughCRLF(inputFunc, inputStream, buffer, &bufferLength); + if (err) + ErrThrow(err); + } + + // could be that everything was header, and we're out of data. + // weird error, but MemHandle it. + if (bufferLength == 0) + { + ErrThrow(exgErrBadData); + } + + + addCr = 0; + while (bufferLength > 0 && + (*boundaryString == nullChr || StrNCompare(buffer, boundaryString, StrLen(boundaryString)) != 0)) + { + // find CR or end of buffer + nextCrChr = StrChr(buffer, crChr); + if (nextCrChr != NULL) + charsToWrite = nextCrChr - buffer; + else + charsToWrite = bufferLength; + + // PREVIEW Aba: Here we have the first line and we can exit + if (descriptionP) + { + if (charsToWrite >= descriptionSize) + charsToWrite = descriptionSize - 1; + + StrNCopy(descriptionP, buffer, charsToWrite); + descriptionP[charsToWrite] = '\0'; + return true; + } + + // if we're going to overflow record, close it out (leave room for terminating null) + if (newRecordSize + charsToWrite + addCr > memoMaxLength) + { + // since we try to stop parsing at each CR, and most records from other sources (MIME) + // should have a CR at least every 76 characters, we probably don't have to worry about + // word wrap. Still, beaming a lot of just plain text could break records on random + // boundaries... + PrvMemoImportFinishRecord(dbP, indexNew, &newRecordH, &newRecordSize, inputStream); + addCr = 0; + numRecordsReceived++; + } + + // Make a record if we need one + if (newRecordH == NULL) + { + indexNew = dmMaxRecordIndex; + newRecordH = DmNewRecord(dbP, (UInt16 *)&indexNew, bufferLength); + if (newRecordH == 0) + ErrThrow(exgMemError); + newRecordSize = 0; + } + + // Write the buffer out to the record + newHandle = DmResizeRecord(dbP, indexNew, newRecordSize + charsToWrite + addCr); + if (newHandle) + newRecordH = newHandle; + else + ErrThrow(exgMemError); + + newRecordP = MemHandleLock(newRecordH); + if (addCr != 0) + DmWrite(newRecordP, newRecordSize++, "\n", 1); + DmWrite(newRecordP, newRecordSize, buffer, charsToWrite); + newRecordSize += charsToWrite; + MemHandleUnlock(newRecordH); + + // Remove the chars written so we can read more into the buffer + if (nextCrChr != NULL) + { + if (charsToWrite < importBufferMaxLength-1) + { + MemMove(buffer, nextCrChr+2, bufferLength-(charsToWrite+2)); // delete LF + bufferLength -= charsToWrite+2; + } + else + // CR/LF was split by end of buffer, so DON'T delete the CR, catch it next time 'round + { + MemMove(buffer, nextCrChr, bufferLength-(charsToWrite)); // don't delete CR or LF + bufferLength -= charsToWrite; + nextCrChr = NULL; + } + } + else + buffer[bufferLength = 0] = nullChr; + + // Now read more + charsRead = inputFunc( inputStream, &buffer[bufferLength], importBufferMaxLength - bufferLength); + bufferLength += charsRead; + buffer[bufferLength] = nullChr; + + if (nextCrChr != NULL) + addCr = 1; + else + addCr = 0; + } // end of segment parser + + // Set the category for the record + if (PrvStreamSocket(inputStream)->appData) { + UInt16 attr; + Err err; + UInt16 categoryID = PrvStreamSocket(inputStream)->appData; + + // Get the attributes + err = DmRecordInfo(dbP, indexNew, &attr, NULL, NULL); + + // Set them to include the category, and mark the record dirty + if ((attr & dmRecAttrCategoryMask) != categoryID) { + attr &= ~dmRecAttrCategoryMask; + attr |= categoryID | dmRecAttrDirty; + err = DmSetRecordInfo(dbP, indexNew, &attr, NULL); + } + } + + PrvMemoImportFinishRecord(dbP, indexNew, &newRecordH, &newRecordSize, inputStream); + numRecordsReceived++; + + // save the uniqueID of the first record we loaded + // we will goto this record when we are done (after sorting) + if (!firstRecordID) + { + // Store the information necessary to navigate to the record inserted. + DmRecordInfo(dbP, indexNew, NULL, &firstRecordID, NULL); + } + + // Now that the record is imported check if we need to import any more + + // Stop if there isn't any more input + if (bufferLength == 0) + break; + + // Stop if the boundary is followed by "--" + if ((*boundaryString != nullChr) + && bufferLength >= StrLen(boundaryString) + 2 + && StrNCompare(&buffer[StrLen(boundaryString)], "--", 2) == 0) + break; + + } while (true); // end of segment parser + } // end of Try + + ErrCatch(inErr) + { + // PREVIEW Aba + if (descriptionP) + return false; + + // Remove the incomplete record + if (inErr) + DmRemoveRecord(dbP, indexNew); + + // if we got at least one record, sort and set goto parameters... + if (firstRecordID) + { + MemoSort(dbP); + PrvMemoSetGoToParams (dbP, PrvStreamSocket(inputStream), firstRecordID); + } + + // return number of records received + *numRecordsReceivedP = numRecordsReceived; + + if ( inErr != exgMemError ) + PrvMemoImportMimeCleanup(dbP, firstRecordID, inputStream, numRecordsReceived, numRecordsReceivedP); + + ErrThrow(inErr); + } ErrEndCatch + + PrvMemoImportMimeCleanup(dbP, firstRecordID, inputStream, numRecordsReceived, numRecordsReceivedP); + + return false; +} + + +/*********************************************************************** + * + * FUNCTION: MemoSendRecord + * + * DESCRIPTION: Beam or send a record. + * + * PARAMETERS: dbP - pointer to the database to add the record to + * recordNum - the record to send + * prefix - the scheme with ":" suffix and optional "?" prefix + * + * RETURNED: true if the record is found and sent + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * roger 5/9/97 Initial Revision + * dje 4/21/00 Add Send support + * dje 4/24/00 Don't specify target creator ID + * + ***********************************************************************/ +extern void MemoSendRecord (DmOpenRef dbP, Int16 recordNum, const Char * const prefix) +{ + MemoDBRecordPtr recordP; + MemHandle recordH; + MemHandle descriptionH; + Err error; + ExgSocketType exgSocket; + MemHandle nameH; + + + // 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 = DmQueryRecord (dbP, recordNum); + recordP = (MemoDBRecordType *) MemHandleLock(recordH); + + // Set the description to be the beginning of the memo + descriptionH = NULL; + exgSocket.description = NULL; + + // Set the exg description to the record's description. + PrvSetDescriptionAndFilename(&recordP->note, &exgSocket.description, + &descriptionH, &exgSocket.name, &nameH, prefix); + + // ABa: Clean superfluous '.' characters + PrvTransferCleanFileName(exgSocket.name); + + exgSocket.length = MemHandleSize(recordH); // rough guess + //exgSocket.target = sysFileCMemo; // commented out 4/24/00 dje + exgSocket.type = (Char *)memoMIMEType; + error = ExgPut(&exgSocket); // put data to destination + if (!error) + { + error = PrvMemoSendRecordTryCatch(dbP, recordNum, recordP, &exgSocket); + + ExgDisconnect(&exgSocket, error); + } + + + // Clean up + if (descriptionH) + { + MemHandleUnlock (descriptionH); + if (MemHandleDataStorage (descriptionH)) + DmReleaseResource(descriptionH); // DOLATER dje - this shouldn't be possible any more + else + MemHandleFree(descriptionH); + } + if (nameH) + { + MemHandleUnlock (nameH); + if (MemHandleDataStorage (nameH)) + DmReleaseResource(nameH); // DOLATER dje - this shouldn't be possible any more + else + MemHandleFree(nameH); + } + MemHandleUnlock(recordH); + + + return; +} + + +/*********************************************************************** + * + * FUNCTION: MemoSendCategory + * + * DESCRIPTION: Beam or send all visible records in a category. + * + * PARAMETERS: dbP - pointer to the database to add the record to + * categoryNum - the category of records to send + * prefix - the scheme with ":" suffix and optional "?" prefix + * noDataAlertID - alert to put up if there is nothing to send + * + * RETURNED: true if any records are found and sent + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * roger 5/9/97 Initial Revision + * dje 4/21/00 Add Send support + * dje 4/24/00 Don't specify target creator ID + * + ***********************************************************************/ +extern void MemoSendCategory (DmOpenRef dbP, UInt16 categoryNum, const Char * const prefix, UInt16 noDataAlertID) +{ + Err error; + Char description[dmCategoryLength]; + UInt16 index; + Boolean foundAtLeastOneRecord; + ExgSocketType exgSocket; + UInt16 mode; + LocalID dbID; + UInt16 cardNo; + Boolean databaseReopened; + + + // If the database was opened to show secret records, reopen it to not see + // secret records. The idea is that secret records are not sent when a + // category is sent. They must be explicitly sent one by one. + DmOpenDatabaseInfo(dbP, &dbID, NULL, &mode, &cardNo, NULL); + if (mode & dmModeShowSecret) + { + dbP = DmOpenDatabase(cardNo, dbID, dmModeReadOnly); + databaseReopened = true; + } + else + databaseReopened = false; + + + // important to init structure to zeros... + MemSet(&exgSocket, sizeof(exgSocket), 0); + + // Make sure there is at least one record in the category. + index = 0; + foundAtLeastOneRecord = false; + while (true) + { + if (DmSeekRecordInCategory(dbP, &index, 0, dmSeekForward, categoryNum) != 0) + break; + + foundAtLeastOneRecord = DmQueryRecord(dbP, index) != 0; + if (foundAtLeastOneRecord) + break; + + + index++; + } + + + // We should send the category because there's at least one record to send. + if (foundAtLeastOneRecord) + { + // Form a description of what's being sent. This will be displayed + // by the system send dialog on the sending and receiving devices. + CategoryGetName (dbP, categoryNum, description); + exgSocket.description = description; + + // Now form a file name + exgSocket.name = MemPtrNew(StrLen(prefix) + StrLen(description) + StrLen(memoSuffix) + sizeOf7BitChar('\0')); + if (exgSocket.name) + { + StrCopy(exgSocket.name, prefix); + StrCat(exgSocket.name, description); + StrCat(exgSocket.name, memoSuffix); + } + + // ABa: Clean superfluous '.' characters + PrvTransferCleanFileName(exgSocket.name); + + exgSocket.length = 0; // rough guess + //exgSocket.target = sysFileCMemo; // commented out 4/24/00 dje + exgSocket.type = (Char *)memoMIMEType; + error = ExgPut(&exgSocket); // put data to destination + + if (!error) + { + error = PrvMemoSendCategoryTryCatch (dbP, categoryNum, &exgSocket, index); + + ExgDisconnect(&exgSocket, error); + } + + // Clean up + if (exgSocket.name) + MemPtrFree(exgSocket.name); + } + else + FrmAlert(noDataAlertID); + + if (databaseReopened) + DmCloseDatabase(dbP); + + return; +} + + +/*********************************************************************** + * + * FUNCTION: MemoReceiveData + * + * DESCRIPTION: Receives data into the output field using the Exg API + * + * PARAMETERS: dbP - database to put received memos in + * exgSocketP - socket from the app code sysAppLaunchCmdExgReceiveData + * numRecordsReceivedP - number of records received is returned here + * + * RETURNED: error code or zero for no error. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * grant 6/25/99 Keep count of received records and return in numRecordsReceivedP + * + ***********************************************************************/ +extern Err MemoReceiveData(DmOpenRef dbP, ExgSocketPtr exgSocketP, UInt16 *numRecordsReceivedP) +{ + volatile Err err; + UInt16 numRecordsReceived; + StreamType stream; + + // initialize new record count + ErrNonFatalDisplayIf(numRecordsReceivedP == NULL, "NULL numRecordsReceivedP"); + *numRecordsReceivedP = 0; + + PrvStreamInit( &stream, exgSocketP); + + // accept will open a progress dialog and wait for your receive commands + err = ExgAccept(exgSocketP); + + if (!err) + { + // Catch errors receiving records. The import routine will clean up the + // incomplete record. This routine displays an error message. + ErrTry + { + // Keep importing records until it can't + while (MemoImportMime(dbP, &stream, PrvReadFunction, false, false, &numRecordsReceived, NULL, 0)) + { + *numRecordsReceivedP += numRecordsReceived; + }; + +// catch the records from the final MemoImportMime + *numRecordsReceivedP += numRecordsReceived; + } + + ErrCatch(inErr) + { + err = inErr; + } ErrEndCatch + + // Aba: A record has been added in the Database iff the GoTo + // uniqueID parameter != 0. + // In the case no record is added, return an error + if (err == errNone && exgSocketP->goToParams.uniqueID == 0) + err = exgErrBadData; + + ExgDisconnect(exgSocketP, err); // closes transfer dialog + err = errNone; // error was reported, so don't return it + } + + return err; +} + + +/************************************************************ + * + * FUNCTION: MemoExportMime + * + * DESCRIPTION: Export a record as a Imc Mime record + * + * PARAMETERS: + * dbP - pointer to the database to export the records from + * index - the record number to export + * recordP - whether the begin statement has been read + * outputStream - pointer to where to export the record to + * outputFunc - function to send output to the stream + * writeUniqueIDs - true to write the record's unique id + * + * RETURNS: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * rsf 8/6/97 Initial Revision + * + *************************************************************/ + +void MemoExportMime(DmOpenRef UNUSED_PARAM(dbP), Int16 UNUSED_PARAM(index), MemoDBRecordType * recordP, + void * outputStream, WriteFunctionF outputFunc, Boolean UNUSED_PARAM(writeUniqueIDs), + Boolean outputMimeInfo) +{ + Char * c; + Char * eolP; + UInt32 len; + + + // Write out all of the memo. All linefeeds must be replaced with CRLF combos. + c = &recordP->note; + + if (outputMimeInfo) + { + if (!ImcStringIsAscii(c)) + outputFunc(outputStream, "Content-Type: Text/plain; charset=ISO-8859-1" crlf, stringZLen); + + outputFunc(outputStream, crlf, stringZLen); + } + + while (*c != '\0') + { + eolP = StrChr(c, linefeedChr); + if (eolP) + { + len = outputFunc( outputStream, c, eolP - c); + + outputFunc(outputStream, crlf, stringZLen); + c = eolP + sizeOf7BitChar(linefeedChr); + } + else if (*c != '\0') + { + eolP = StrChr(c, '\0'); + len = outputFunc( outputStream, c, eolP - c); + + c = eolP; + } + } + outputFunc(outputStream, crlf, stringZLen); // always end with an extra crlf +} + +/*********************************************************************** + * + * FUNCTION: MemoTransferPreview + * + * DESCRIPTION: Create a short string preview of the data coming in. + * + * PARAMETERS: infoP - the preview info from the command parameter block + * of the sysAppLaunchCmdExgPreview launch + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * ABa 11/10/00 Created + * + ***********************************************************************/ +void MemoTransferPreview(ExgPreviewInfoType *infoP) +{ + volatile Err err; + UInt16 numRecordsReceived; + StreamType stream; + + if (infoP->op == exgPreviewQuery) + { + infoP->types = exgPreviewShortString; + return; + } + if (infoP->op != exgPreviewShortString) + { + infoP->error = exgErrNotSupported; + return; + } + + // if we have a description we don't have to parse the vObject + if (infoP->socketP->description && *infoP->socketP->description) + { + StrNCopy(infoP->string, infoP->socketP->description, infoP->size - 1); + infoP->string[infoP->size - 1] = 0; + infoP->error = errNone; + return; + } + + PrvStreamInit(&stream, infoP->socketP); + + err = ExgAccept(infoP->socketP); + + if (!err) + { + ErrTry + { + MemoImportMime((DmOpenRef) NULL, &stream, PrvReadFunction, false, false, &numRecordsReceived, infoP->string, infoP->size); + } + + ErrCatch(inErr) + { + err = inErr; + } ErrEndCatch + + ExgDisconnect(infoP->socketP, err); // closes transfer dialog + } + + infoP->error = err; +} + + +#pragma mark - + +/*********************************************************************** + * + * FUNCTION: PrvStreamInit + * + * DESCRIPTION: Function to put Initialize a stream socket. + * + * PARAMETERS: streamP - the output stream + * exgSocketP - pointer to an intitialized exgSocket + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * gavin 10/5/99 Initial revision + * + ***********************************************************************/ +static void PrvStreamInit(StreamType *streamP, ExgSocketPtr exgSocketP) +{ + streamP->socket = exgSocketP; + streamP->bufSize = maxStreamBuf; + streamP->pos = 0; + streamP->len = 0; +} + +/*********************************************************************** + * + * FUNCTION: PrvStreamFlush + * + * DESCRIPTION: Function to put a string to the exg transport. + * + * PARAMETERS: streamP - the output stream + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * gavin 10/5/99 Initial revision + * + ***********************************************************************/ +static void PrvStreamFlush(StreamType *streamP) +{ + Err err = 0; + while (streamP->len && !err) + streamP->len -= ExgSend(streamP->socket,streamP->buf,streamP->len,&err); + +} + +/*********************************************************************** + * + * FUNCTION: PrvStreamWrite + * + * DESCRIPTION: Function to put a string to the exg transport. + * + * PARAMETERS: streamP - the output stream + * stringP - the string to put + * + * RETURNED: nothing + * If the all the string isn't sent an error is thrown using ErrThrow. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * gavin 10/5/99 Initial revision + * + ***********************************************************************/ +static UInt32 PrvStreamWrite(StreamType *streamP, const Char * stringP, Int32 length, Err *errP) +{ + UInt32 count = 0; + *errP = 0; + + while (count < length && !*errP) + { + if (streamP->len < streamP->bufSize) + { + streamP->buf[streamP->len++] = *stringP++; + count++; + } + else + streamP->len -= ExgSend(streamP->socket, streamP->buf, streamP->len, errP); + } + return count; +} + +/*********************************************************************** + * + * FUNCTION: PrvStreamRead + * + * DESCRIPTION: Function to get a character from the input stream. + * + * PARAMETERS: streamP - the output stream + * + * RETURNED: a character of EOF if no more data + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * gavin 10/5/99 Initial revision + * + ***********************************************************************/ +static UInt32 PrvStreamRead(StreamType * streamP, Char *bufP, UInt32 length, Err *errP) +{ + UInt32 count = 0; + + *errP = 0; + while (count < length) + { + if (streamP->pos < streamP->len) + bufP[count++] = streamP->buf[streamP->pos++]; + else + { streamP->pos = 0; + streamP->len = ExgReceive(streamP->socket, streamP->buf, streamP->bufSize, errP); + if (!streamP->len || *errP) + break; + } + } + return count; +} + +/*********************************************************************** + * + * FUNCTION: PrvStreamSocket + * + * DESCRIPTION: returns the socket from a stream. + * + * PARAMETERS: streamP - the output stream + * + * RETURNED: The socket associated with the stream + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * gavin 10/5/99 Initial revision + * + ***********************************************************************/ +static ExgSocketPtr PrvStreamSocket(StreamType *streamP) +{ + return streamP->socket; +} + +/*********************************************************************** + * + * FUNCTION: GetChar + * + * DESCRIPTION: Function to get a character from the exg transport. + * + * PARAMETERS: exgSocketP - the exg connection + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * roger 8/15/97 Initial Revision + * + ***********************************************************************/ +static UInt32 PrvReadFunction(const void * stream, Char * bufferP, UInt32 length) +{ + Err err; + UInt32 bytesRead; + bytesRead = PrvStreamRead((StreamType *)stream, bufferP, length, &err); + if (err) + ErrThrow(err); + return bytesRead; +} + + +/*********************************************************************** + * + * FUNCTION: PutString + * + * DESCRIPTION: Function to put a string to the exg transport. + * + * PARAMETERS: exgSocketP - the exg connection + * stringP - the string to put + * + * RETURNED: nothing + * If the all the string isn't sent an error is thrown using ErrThrow. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * roger 8/15/97 Initial Revision + * + ***********************************************************************/ +static UInt32 PrvWriteFunction(void * stream, const Char * const bufferP, Int32 length) +{ + UInt32 len; + Err err; + + // passing -1 length will assume a null terminated string + if (length == -1) length = StrLen(bufferP); + + len = PrvStreamWrite( stream, bufferP, length, &err); + + // If the bytes were not sent throw an error. + if ((len == 0 && length > 0) || err) + ErrThrow(err); + + return len; +} + + +/*********************************************************************** + * + * 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: PrvSetDescriptionAndFilename + * + * DESCRIPTION: Derive and allocate a decription and filename from some text. + * The filename will be a URL which includes the specified scheme. + * + * 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 PrvSetDescriptionAndFilename(Char * textP, Char **descriptionPP, + MemHandle *descriptionHP, Char **filenamePP, MemHandle *filenameHP, const Char * const prefix) +{ + Char * descriptionP; + Int16 descriptionSize; + Coord 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); + } + + + 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(memoSuffix) + sizeOf7BitChar('\0')); + filenameP = MemHandleLock(*filenameHP); + if (filenameP) + { + StrCopy(filenameP, prefix); + MemMove(&filenameP[schemeLength], descriptionP, filenameLength); + MemMove(&filenameP[schemeLength + filenameLength], memoSuffix, + StrLen(memoSuffix) + 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: PrvMemoSendRecordTryCatch + * + * 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 PrvMemoSendRecordTryCatch (DmOpenRef dbP, Int16 recordNum, + MemoDBRecordPtr recordP, ExgSocketPtr exgSocketP) +{ + volatile Err error = 0; + StreamType stream; + + PrvStreamInit(&stream, exgSocketP); + + // 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 + { + MemoExportMime(dbP, recordNum, recordP, &stream, PrvWriteFunction, true, false); + } + + ErrCatch(inErr) + { + error = inErr; + } ErrEndCatch + + PrvStreamFlush( &stream); + return error; +} + + +/*********************************************************************** + * + * FUNCTION: PrvMemoSendCategoryTryCatch + * + * DESCRIPTION: Send all visible records in a category. + * + * PARAMETERS: dbP - pointer to the database to add the record to + * categoryNum - the category of records to send + * exgSocketP - the exchange socket used to send + * index - the record number of the first record in the category to send + * + * RETURNED: 0 if there's no error + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * roger 12/11/97 Initial Revision + * + ***********************************************************************/ +static Err PrvMemoSendCategoryTryCatch (DmOpenRef dbP, UInt16 categoryNum, + ExgSocketPtr exgSocketP, UInt16 index) +{ + volatile Err error = 0; + volatile MemHandle outRecordH = 0; + MemoDBRecordType *outRecordP; + StreamType stream; + + // 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 + { + + PrvStreamInit(&stream, exgSocketP); + + // Write out the beginning of a multipart mime message + PrvWriteFunction(&stream, + mimeVersionString + "Content-type: multipart/mixed; boundary=\"" simpleBoundary "\"" crlf crlf, stringZLen); + + // Loop through all records in the category. + while (DmSeekRecordInCategory(dbP, &index, 0, dmSeekForward, categoryNum) == 0) + { + // Emit the record. If the record is private do not emit it. + outRecordH = DmQueryRecord (dbP, index); + + if (outRecordH != 0) + { + outRecordP = (MemoDBRecordType *) MemHandleLock(outRecordH); + + // Emit a mime boundary + PrvWriteFunction(&stream, delimiter crlf, stringZLen); + + MemoExportMime(dbP, index, outRecordP, &stream, PrvWriteFunction, true, true); + + MemHandleUnlock(outRecordH); + } + + index++; + } + outRecordH = 0; + dbP = 0; + + // All done. Write out an epilogue. + PrvWriteFunction(&stream, delimiter "--" crlf crlf, stringZLen); + } + + ErrCatch(inErr) + { + error = inErr; + + if (outRecordH) + MemHandleUnlock(outRecordH); + } ErrEndCatch + + PrvStreamFlush(&stream); + + return error; +} + +/*********************************************************************** + * + * FUNCTION: PrvMemoSetGoToParams + * + * DESCRIPTION: Store the information necessary to navigate to the + * record inserted into the launch code's parameter block. + * + * PARAMETERS: dbP - pointer to the database to add the record to + * exgSocketP - parameter block passed with the launch code + * uniqueID - unique id of the record inserted + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 10/17/97 Created + * + ***********************************************************************/ +static void PrvMemoSetGoToParams (DmOpenRef dbP, ExgSocketPtr exgSocketP, UInt32 uniqueID) +{ + UInt16 recordNum; + UInt16 cardNo; + LocalID dbID; + + + if (! uniqueID) return; + + DmOpenDatabaseInfo (dbP, &dbID, NULL, NULL, &cardNo, NULL); + + // The this the the first record inserted, save the information + // necessary to navigate to the record. + if (! exgSocketP->goToParams.uniqueID) + { + DmFindRecordByID (dbP, uniqueID, &recordNum); + + exgSocketP->goToCreator = sysFileCMemo; + exgSocketP->goToParams.uniqueID = uniqueID; + exgSocketP->goToParams.dbID = dbID; + exgSocketP->goToParams.dbCardNo = cardNo; + exgSocketP->goToParams.recordNum = recordNum; + } + + // If we already have a record then make sure the record index + // is still correct. Don't update the index if the record is not + // in your the app's database. + else if (dbID == exgSocketP->goToParams.dbID && + cardNo == exgSocketP->goToParams.dbCardNo) + { + DmFindRecordByID (dbP, exgSocketP->goToParams.uniqueID, &recordNum); + + exgSocketP->goToParams.recordNum = recordNum; + } +} + + +/************************************************************ + * + * FUNCTION: PrvReadThroughCRLF + * + * DESCRIPTION: Consume data up to and including the next CRLF. + * + * PARAMETERS: + * inputStreamP - pointer to where to import from + * bufferP - where the input stream is stored + * bufferLengthP - the length of bufferP used + * + * RETURNED: error code or zero for no error. + * + * ASSUMPTIONS: + * Buffer is full when called + * Buffer is big enough to hold a full line (including LF) + * ...so CR/LF will never split + * END CONDITION: + * Buffer is full when routine exits. + * + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * bob 1/26/98 initial revision + * + *************************************************************/ +static Err PrvReadThroughCRLF(ReadFunctionF inputFunc, void * inputStreamP, Char * bufferP, UInt16 * bufferLengthP) +{ + char *c; + UInt16 charsRead; + Err err = 0; + Boolean gotOne = false; + + while (*bufferLengthP > 0 && !gotOne) + { + c = StrChr(bufferP, crChr); + if (c == NULL) + c = &bufferP[*bufferLengthP]; // end of the buffer + else if (c < bufferP + *bufferLengthP - 1) // guard against buffer splitting cr/lf + { + c += sizeOf7BitChar(crChr) + sizeOf7BitChar(linefeedChr); + gotOne = true; + } + + // Consume everything up to the CR/NULL + MemMove(bufferP, c, &bufferP[*bufferLengthP] - c); + *bufferLengthP = &bufferP[*bufferLengthP] - c; + + // Read in more chars + charsRead = inputFunc(inputStreamP, bufferP + *bufferLengthP, importBufferMaxLength - *bufferLengthP); + *bufferLengthP += charsRead; + bufferP[*bufferLengthP] = nullChr; + } + + return err; +} + + +/************************************************************ + * + * FUNCTION: PrvMemoImportFinishRecord + * + * DESCRIPTION: Make sure record is null terminated, and close it. + * + * PARAMETERS: + * dbP - pointer to the database to add the record to + * indexNew - index of new record + * newRecordH - MemHandle to new record + * newRecordSize - bytes currently in new record + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * bob 1998-02-05 Moved out of MemoImportMime + * + *************************************************************/ +static void PrvMemoImportFinishRecord(DmOpenRef dbP, UInt16 indexNew, MemHandle *newRecordHPtr, UInt16 *newRecordSizePtr, void * inputStream) +{ + Char * newRecordP; + MemHandle newHandle; // Used to follow resized records which move + + + ErrNonFatalDisplayIf(*newRecordHPtr == NULL, "Null record MemHandle."); + + // Make sure the record is nullChr terminated + newRecordP = MemHandleLock(*newRecordHPtr); + if (newRecordP[*newRecordSizePtr - sizeof(char)] != nullChr) + { + MemHandleUnlock(*newRecordHPtr); + newHandle = DmResizeRecord(dbP, indexNew, *newRecordSizePtr + sizeOf7BitChar(nullChr)); + if (newHandle) + *newRecordHPtr = newHandle; + else + ErrThrow(exgMemError); + + newRecordP = MemHandleLock(*newRecordHPtr); + DmWrite(newRecordP, *newRecordSizePtr, "", sizeOf7BitChar(nullChr)); + } + + // let the record go + MemHandleUnlock(*newRecordHPtr); + DmReleaseRecord(dbP, indexNew, true); + + + *newRecordHPtr = NULL; + *newRecordSizePtr = 0; +} + + +/************************************************************ + * + * FUNCTION: PrvMemoImportMimeCleanup + * + * DESCRIPTION: Cleanup function for MemoImportMime + * + * PARAMETERS: + * dbP - pointer to the database to add the record to + * firstRecordID - uniqueID of the first record we loaded + * inputStream - pointer to where to import the record from + * numRecordsReceived - number of records received + * numRecordsReceivedP - pointer to the number of records received + * + * RETURNS: None + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * FPa 11/22/00 Initial Revision + * + *************************************************************/ +void PrvMemoImportMimeCleanup(DmOpenRef dbP, UInt32 firstRecordID, void* inputStream, UInt16 numRecordsReceived, UInt16* numRecordsReceivedP) +{ + // if we got at least one record, sort and set goto parameters... + if (firstRecordID) + { + MemoSort(dbP); + PrvMemoSetGoToParams (dbP, PrvStreamSocket(inputStream), firstRecordID); + } + + // return number of records received + *numRecordsReceivedP = numRecordsReceived; +} diff --git a/handera-sdk-105/examples/ExampleI/Src/Trg.h b/handera-sdk-105/examples/ExampleI/Src/Trg.h new file mode 100644 index 0000000..c220ea8 --- /dev/null +++ b/handera-sdk-105/examples/ExampleI/Src/Trg.h @@ -0,0 +1,56 @@ +/*********************************************************************** + * + * Copyright (c) 2001 TRG, All Rights Reserved + * + * FileName: + * TRG.h + * + * Description: + * + * + * History: + * 7-10-00 -- original version + * + **********************************************************************/ +#ifndef _TRG_H_ +#define _TRG_H_ + +#include +#include + +#define TRGSysFtrID 'TRG ' + +#ifdef __GNUC__ + +#define _TRG_CALL_WITH_16BIT_SELECTOR(table, vector, selector)\ + __attribute__ ((__callseq__ (\ + "move.w #" _Str(selector) ",%%d2; "\ + "trap #" _Str(table) "; dc.w " _Str(vector) ))) + +#elif defined (__MWERKS__) /* The equivalent in CodeWarrior syntax */ + +#define _TRG_CALL_WITH_16BIT_SELECTOR(table, vector, selector) \ + = { 0x343C, selector, 0x4E40 + table, vector } + +#endif + +#define TRG_TRAP(sel) \ + _TRG_CALL_WITH_16BIT_SELECTOR(_SYSTEM_TABLE, sysTrapOEMDispatch, sel) + +#ifdef BUILDING_EXTENSION + #define EXT_TRAP(x) +#else + #define EXT_TRAP(x) TRG_TRAP(x) +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + + +#endif diff --git a/handera-sdk-105/examples/ExampleI/Src/Vga.h b/handera-sdk-105/examples/ExampleI/Src/Vga.h new file mode 100644 index 0000000..38d4cb9 --- /dev/null +++ b/handera-sdk-105/examples/ExampleI/Src/Vga.h @@ -0,0 +1,368 @@ +/**************************************************************************** + * + * Copyright (c) 2001, TRG, All Rights Reserved + * + *--------------------------------------------------------------------------- + * FileName: + * Vga.h + * + * Description: + * VGA API definitions. + * + * + ****************************************************************************/ + +#ifndef __VGA_H__ +#define __VGA_H__ + +#include "Trg.h" + +#define TRGVgaFtrNum 2 + +/*-------------------------------------------------------------------------- + * Vga result codes + * (oemErrorClass is reserved for Palm licensees). + *-------------------------------------------------------------------------*/ +#define vgaErrorClass (oemErrorClass | 0x200) + +#define vgaErrUnimplemented (vgaErrorClass | 0) // function not implemented (on this hardware) +#define vgaErrBadParam (vgaErrorClass | 1) // invalid parameter +#define vgaErrModeUnsupported (vgaErrorClass | 2) // does not support screen mode +#define vgaErrScreenLocked (vgaErrorClass | 3) // ??? +#define vgaErrFontUndefined (vgaErrorClass | 4) // ??? + +/*--------------------------------------------------------------------------- + * Extension Installed + *--------------------------------------------------------------------------*/ +#define _TRGVGAFeaturePresent(versionPtr) \ + (Boolean)(FtrGet(TRGSysFtrID, TRGVgaFtrNum, versionPtr) == 0) + + +/*--------------------------------------------------------------------------- + * Notification that the screen area changed (silk minimize/maximized, rotation) + *--------------------------------------------------------------------------*/ +#define displayExtentChangedEvent ((eventsEnum)(firstUserEvent-2)) +typedef struct displayExtentChangedDataType +{ + RectangleType oldDim; + RectangleType newDim; +} displayExtentChangedDataType; + +/*--------------------------------------------------------------------------- + * Macro to simplify getting the data out of the event structure. + * Example: + * yDiff = displayExtentChangedData(eventP)->newDim->extent.y - + * displayExtentChangedData(eventP)->oldDim->extent.y; + *--------------------------------------------------------------------------*/ +#define displayExtentChangedData(eventP) ((displayExtentChangedDataType *)(&((eventP)->data.generic))) + +/*--------------------------------------------------------------------------- + * Vga Font ID's + *--------------------------------------------------------------------------*/ +enum vgaFontID { + vga4x8FixedFont = 0x00, + vga10x16FixedFont, + vga14x22FixedFont +}; + +typedef enum vgaFontID VgaFontID; + +/*--------------------------------------------------------------------------- + * Screen and rotation modes + *--------------------------------------------------------------------------*/ +typedef enum +{ + screenModeScaleToFit = 0, + screenMode1To1, + screenModeOffset //System Use Only +} VgaScreenModeType; + +typedef enum +{ + rotateModeNone = 0, + rotateMode90, + rotateMode180, + rotateMode270 +} VgaRotateModeType; + +/*--------------------------------------------------------------------------- + * Legacy app display modes. + *--------------------------------------------------------------------------*/ +typedef enum +{ + offsetModeTopLeft = 0, + offsetModeTopCenter, + offsetModeTopRight, + offsetModeCenterLeft, + offsetModeCenterCenter, + offsetModeCenterRight, + offsetModeBottomLeft, + offsetModeBottomCenter, + offsetModeBottomRight +} VgaOffsetModeType; + +/*--------------------------------------------------------------------------- + * Font Select Types + *--------------------------------------------------------------------------*/ +typedef enum +{ + vgaFontSelectPalm = 0, + vgaFontSelectVgaText +} VgaFontSelectType; + +/*--------------------------------------------------------------------------- + * Form Modify Types + *--------------------------------------------------------------------------*/ +typedef enum +{ + vgaFormModify160To240 = 0 +} VgaFormModifyType; + +/*--------------------------------------------------------------------------- + * Vga Screen State + *--------------------------------------------------------------------------*/ +typedef struct VgaScreenStateType +{ + VgaScreenModeType mode; + VgaRotateModeType rotate; + VgaOffsetModeType offset; +} VgaScreenStateType; + +/*--------------------------------------------------------------------------- + * Vga System State + *--------------------------------------------------------------------------*/ +typedef struct VgaSystemStateType +{ + VgaScreenModeType screenMode; + Int16 offset_X; + Int16 offset_Y; + + UInt8 draw_override; + UInt8 list_draw; + UInt8 use_large_font; + UInt8 use_large_nontextfont; + + UInt8 reserved[16]; +} VgaSystemStateType; + + +#ifdef __cplusplus +extern "C" { +#endif + +#define trgMinVgaFunction 0x0200 +#define trgGetScreenMode (trgMinVgaFunction + 0) +#define trgSetScreenMode (trgMinVgaFunction + 1) + +#define trgBitmapExpandedExtent (trgMinVgaFunction + 2) +#define trgNOP (trgMinVgaFunction + 3) //Remove +#define trgWinDrawBitmapExpanded (trgMinVgaFunction + 4) + +#define trgBaseToVgaFont (trgMinVgaFunction + 5) +#define trgFontSelect (trgMinVgaFunction + 6) +#define trgGetFrmTitleHeight (trgMinVgaFunction + 7) +#define trgIsVgaFont (trgMinVgaFunction + 8) +#define trgVgaEnable (trgMinVgaFunction + 9) +#define trgVgaDisable (trgMinVgaFunction + 10) +#define trgVgaIsEnabled (trgMinVgaFunction + 11) +#define trgGetLegacyMode (trgMinVgaFunction + 12) +#define trgSetLegacyMode (trgMinVgaFunction + 13) + +#define trgTableUseBaseFont (trgMinVgaFunction + 14) + +#define trgFrmModify (trgMinVgaFunction + 15) + +#define trgVgaToBaseFont (trgMinVgaFunction + 16) + +#define trgReloadAppPrefs (trgMinVgaFunction + 17) + +#define trgSaveScreenState (trgMinVgaFunction + 18) +#define trgRestoreScreenState (trgMinVgaFunction + 19) + +#define trgRotateSelect (trgMinVgaFunction + 20) + +#define trgGetSystemState (trgMinVgaFunction + 21) + +#define trgGetFontPtr (trgMinVgaFunction + 22) +#define trgSetFontPtr (trgMinVgaFunction + 23) +#define trgGetNumVgaFonts (trgMinVgaFunction + 24) +#define trgPalmFontID (trgMinVgaFunction + 25) + +#define trgMaxVgaFunction 0x0219 + + +/******************************************************************** + * VGA API Prototypes + ********************************************************************/ + +/*--------------------------------------------------------------------------- + * Returns the current mode and rotation settings + *--------------------------------------------------------------------------*/ +extern void VgaGetScreenMode(VgaScreenModeType *mode, VgaRotateModeType *rotation) + EXT_TRAP(trgGetScreenMode); + +/*--------------------------------------------------------------------------- + * Set current screen mode. + *--------------------------------------------------------------------------*/ +extern Err VgaSetScreenMode(VgaScreenModeType mode, VgaRotateModeType rotation) + EXT_TRAP(trgSetScreenMode); + +/*--------------------------------------------------------------------------- + * Pass in non-expanded bitmap and destination, returns the X & Y extent + * the expanded bitmap. + *--------------------------------------------------------------------------*/ +extern void VgaBitmapExpandedExtent(BitmapPtr bitmapP, Coord *extentX, Coord *extentY) + EXT_TRAP(trgBitmapExpandedExtent); + +/*--------------------------------------------------------------------------- + * Draw the bitmap at 1.5 scale. This is needed for non 160x160 applications + * that need to expand existing small bitmaps. (IE Launcher) + *--------------------------------------------------------------------------*/ +extern void VgaWinDrawBitmapExpanded(BitmapPtr bitmapP, Coord x, Coord y) + EXT_TRAP(trgWinDrawBitmapExpanded); + +/*--------------------------------------------------------------------------- + * Take the Palm font and return the 1.5 scale font + *--------------------------------------------------------------------------*/ +extern FontID VgaBaseToVgaFont(FontID font) + EXT_TRAP(trgBaseToVgaFont); + +/*--------------------------------------------------------------------------- + * Take the Vga font and return the Palm font + *--------------------------------------------------------------------------*/ +extern FontID VgaVgaToBaseFont(FontID font) + EXT_TRAP(trgVgaToBaseFont); + +/*--------------------------------------------------------------------------- + * Display the TRG Select Font dialog which shows the 4 Palm text fonts + * plus the 4 equivalent TRG larger fonts. + *--------------------------------------------------------------------------*/ +extern FontID VgaFontSelect(VgaFontSelectType selectFormType, FontID fontID) + EXT_TRAP(trgFontSelect); + +/*--------------------------------------------------------------------------- + * Is font a 1.5 expanded font. + *--------------------------------------------------------------------------*/ +extern Boolean VgaIsVgaFont(FontID font) + EXT_TRAP(trgIsVgaFont); + +/*--------------------------------------------------------------------------- + * Use small Palm font when drawing tableItemStyles excluding customTableItem + * which determines its + *--------------------------------------------------------------------------*/ +extern void VgaTableUseBaseFont(TablePtr table, Boolean on) + EXT_TRAP(trgTableUseBaseFont); + +/*--------------------------------------------------------------------------- + * Return the heigth of the Titlebar. Necessary for placement of form text + * and objects + *--------------------------------------------------------------------------*/ +extern UInt16 VgaGetFrmTitleHeight(void) + EXT_TRAP(trgGetFrmTitleHeight); + +/*--------------------------------------------------------------------------- + * VgaEnable + *--------------------------------------------------------------------------*/ +extern void VgaEnable(Boolean redraw) + EXT_TRAP(trgVgaEnable); + +/*--------------------------------------------------------------------------- + * VgaDisable + *--------------------------------------------------------------------------*/ +extern void VgaDisable(Boolean redraw) + EXT_TRAP(trgVgaDisable); + +/*--------------------------------------------------------------------------- + * VgaIsEnabled + *--------------------------------------------------------------------------*/ +extern Boolean VgaIsEnabled(void) + EXT_TRAP(trgVgaIsEnabled); + +/*--------------------------------------------------------------------------- + * VgaGetLegacyMode + *--------------------------------------------------------------------------*/ +extern void VgaGetLegacyMode(VgaScreenModeType *viewMode, VgaOffsetModeType *offsetMode) + EXT_TRAP(trgGetLegacyMode); + +/*--------------------------------------------------------------------------- + * VgaSetLegacyMode + *--------------------------------------------------------------------------*/ +extern void VgaSetLegacyMode(VgaScreenModeType viewMode, VgaOffsetModeType offsetMode) + EXT_TRAP(trgSetLegacyMode); + +/*--------------------------------------------------------------------------- + * VgaFormModify + *--------------------------------------------------------------------------*/ +extern Err VgaFormModify(FormType *frmP, VgaFormModifyType type) + EXT_TRAP(trgFrmModify); + +/*--------------------------------------------------------------------------- + * VgaFormModify + * + * #define to allow the old VgaFrmModify routine. Please change your code to + * use the new VgaFormModify routine above. This #define will be removed in + * the future. + *--------------------------------------------------------------------------*/ +#define VgaFrmModify(frmP, type) (VgaFormModify((frmP, type))) + +/*--------------------------------------------------------------------------- + * VgaLoadAppPrefs + *--------------------------------------------------------------------------*/ +extern void VgaReloadAppPrefs(void) + EXT_TRAP(trgReloadAppPrefs); + +/*--------------------------------------------------------------------------- + * VgaSaveScreenState + *--------------------------------------------------------------------------*/ +extern void VgaSaveScreenState(VgaScreenStateType *state) + EXT_TRAP(trgSaveScreenState); + +/*--------------------------------------------------------------------------- + * VgaRestoreScreenState + *--------------------------------------------------------------------------*/ +extern Err VgaRestoreScreenState(VgaScreenStateType *state) + EXT_TRAP(trgRestoreScreenState); + +/*--------------------------------------------------------------------------- + * VgaRotateSelect + *--------------------------------------------------------------------------*/ +extern VgaRotateModeType VgaRotateSelect (VgaRotateModeType rotateMode) + EXT_TRAP(trgRotateSelect); + +/*--------------------------------------------------------------------------- + * VgaGetSystemState + *--------------------------------------------------------------------------*/ +extern void VgaGetSystemState(VgaSystemStateType *pState) + EXT_TRAP(trgGetSystemState); + +/*--------------------------------------------------------------------------- + * VgaGetFontPtr + *--------------------------------------------------------------------------*/ +extern Err VgaGetFontPtr(FontID font, FontPtr *fontP) + EXT_TRAP(trgGetFontPtr); + +/*--------------------------------------------------------------------------- + * VgaSetFontPtr + *--------------------------------------------------------------------------*/ +extern Err VgaSetFontPtr(FontID font, FontPtr fontP) + EXT_TRAP(trgSetFontPtr); + +/*--------------------------------------------------------------------------- + * VgaGetNumVgaFonts + *--------------------------------------------------------------------------*/ +extern UInt16 VgaGetNumVgaFonts(void) + EXT_TRAP(trgGetNumVgaFonts); + + +/*--------------------------------------------------------------------------- + * VgaPalmFontID + *--------------------------------------------------------------------------*/ +extern FontID VgaPalmFontID(VgaFontID font) + EXT_TRAP(trgPalmFontID); + +#ifdef __cplusplus +} +#endif + + +#endif // __VGA_H__ diff --git a/handera-sdk-105/examples/ExampleI/TRGChangeLog.txt b/handera-sdk-105/examples/ExampleI/TRGChangeLog.txt new file mode 100644 index 0000000..57105d5 --- /dev/null +++ b/handera-sdk-105/examples/ExampleI/TRGChangeLog.txt @@ -0,0 +1,57 @@ +Changes required to convert MemoPad to a QVGA aware application. +Based on the PalmOS 4.0 SDK version, all changes are surrounded by: +/* TRG */ +changes +/* end TRG */ +to make them easier to find. All code changes are within MemoMain.c + +1. Resource changes. + + a. Add QVGA IconsAdd IconID 2000 and 2001 which are 32x32 (1.5x icon view icon) and + 22x15 (1.5x list view icon). + b. Change ListView table number of rows to 25. + c. Add HandEra.r resource to indicate it is a Handera 330 aware application. + d. Fix typo in AlertID 2000, remove extra space before first period. + +2. Support the larger screen. Switching to 1to1 mode (240x240) gives + access to the additional fonts and allows supporting the minimized + silk screen. Note that if you have any bitmaps, you'll need to add + 1.5x versions at originalID + 0x1000 to your resources. + + a. Add #include "vga.h" to the top. + b. Add a vgaExists global (Boolean). + c. Add a check for vga existence in StartApplication() and set the + vgaExists global. + d. Add a call to VgaSetScreenMode() in StartApplication(). + e. Add call to VgaFormModify() in EditViewHandleEvent and + ListViewHandleEvent frmOpenEvent and frmGotoEvent cases. + f. Add VgaFormModify() to the modal forms in: DetailsInit(), + DeleteRecord(), EditViewDeleteRecord(), and PreferencesInit(). + +3. Cleanup font issues. The default font needs to be changed to the + standard font instead of the smallest. Also, calls to + VgaTableUseBaseFont() need to be put in where the table is using + small fonts. + + a. ListViewHandleEvent() frmOpenCase, add VgaTableUseBaseFont(, !VgaIsVgaFont()). + b. SelectFont() add VgaTableUseBaseFont(, !VgaIsVgaFont()) if it is ListView. + c. MemoLoadPrefs() add VgaBaseToVgaFont() to get the correct default font. + d. ListViewDisplayMask() adjust for new lock bitmap size and use new bitmap + when using a Vga font. + +4. Support the virtual silk screen. + + a. Add functions EditViewResizeForm() and ListViewResizeForm(), + and the utility functions PrvMoveObject(), PrvResizeObject(), + and PrvFrmGetGSI(). + b. Call appropriate ResizeForm function from frmOpenEvent to + handle the case where the app is launched with the silk minimized. + c. Add vgaChangedEvent to ListViewHandleEvent and EditViewHandleEvent + and call appropriate ResizeForm(). + +5. Support one-hand operation. + a. Add handler for chrCarriageReturn and chrEscape to EditViewHandleEvent() + which returns to the ListView. + b. Add handlers for chrCarriageReturn, vchrNextField, and vchrPrevField + to ListViewHandleEvent(). + c. Unselect item if category changes. diff --git a/handera-sdk-105/examples/ExampleJ/ExampleJ.mcp b/handera-sdk-105/examples/ExampleJ/ExampleJ.mcp new file mode 100644 index 0000000..f61741b Binary files /dev/null and b/handera-sdk-105/examples/ExampleJ/ExampleJ.mcp differ diff --git a/handera-sdk-105/examples/ExampleJ/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleJ/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..34b8f6b Binary files /dev/null and b/handera-sdk-105/examples/ExampleJ/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleJ/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleJ/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleJ/Src/MainForm.c b/handera-sdk-105/examples/ExampleJ/Src/MainForm.c new file mode 100644 index 0000000..e06a9c1 --- /dev/null +++ b/handera-sdk-105/examples/ExampleJ/Src/MainForm.c @@ -0,0 +1,772 @@ +/****************************************************************************** + * + * File: MainForm.c + * + * Project : Example 7 + * + *****************************************************************************/ + +#include +#include +#include "StarterRsc.h" + +#include "Vga.h" +#include "Audio.h" +#include "TrgChars.h" +#include "Wave.h" +#include "starter.h" +#include "MainForm.h" + +/*********************************************************************** + * + * Local Types + * + ***********************************************************************/ +typedef enum { + audioStateNoVolume, + audioStateNoFile, + audioStateOpen, + audioStatePlaying, + audioStateRecording +} AudioStateType; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ +extern Boolean vgaPresent; +extern Boolean auxButtonPresent; +extern Boolean cardChangedOccurred; + +/*********************************************************************** + * + * Local Constants + * + ***********************************************************************/ +#define WAVE_FILE "ExampleJ.wav" + +#define recordStartEvent ((eventsEnum)((Int16)firstUserEvent)) + +/*********************************************************************** + * + * Local Functions + * + ***********************************************************************/ +static void *GetObjectPtr (UInt16 objectID); +static void SetControls (void); +static void SetSliderPercent (FormPtr frmP, UInt16 percent); +static void HideObject (UInt16 id); +static void ShowObject (UInt16 id); + +static void HandlePlayButton (void); +static void HandleStopButton (void); +static void HandleRecordButton (void); +static void HandleProgress (EventPtr eventP); +static void HandlePauseButton (void); +static void HandleSliderControl(EventPtr eventP); + + +/*********************************************************************** + * + * Local Variables + * + ***********************************************************************/ +static AudioStateType audioState; +static Boolean canRecord; +static Boolean launchedFromButton; + + + /*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + + +/*********************************************************************** + * + * FUNCTION: PrvMoveObject + * + * DESCRIPTION: This routine moves an object vertically within a form. + * + * PARAMETERS: + * + * RETURNED: nothing + * + ***********************************************************************/ +static void PrvMoveObject(FormPtr frmP, UInt16 objIndex, Coord y_diff, Boolean draw) +{ + RectangleType r; + + FrmGetObjectBounds(frmP, objIndex, &r); + if (draw) + { + RctInsetRectangle(&r, -2); //need to erase the frame as well + WinEraseRectangle(&r, 0); + RctInsetRectangle(&r, 2); + } + r.topLeft.y += y_diff; + FrmSetObjectBounds(frmP, objIndex, &r); +} + + +/*********************************************************************** + * + * FUNCTION: SetSliderPercent + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void SetSliderPercent(FormPtr frmP, UInt16 percent) +{ + ControlPtr sliderP; + + sliderP = (ControlPtr)GetObjectPtr(MainProgressSliderControl); + CtlSetSliderValues(sliderP, NULL, NULL, NULL, &percent); +} + + /*********************************************************************** + * + * FUNCTION: HideObject + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void HideObject(UInt16 id) +{ + UInt16 obj_index; + + obj_index = FrmGetObjectIndex(FrmGetActiveForm(), id); + FrmHideObject(FrmGetActiveForm(), obj_index); +} + +/*********************************************************************** + * + * FUNCTION: ShowObject + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void ShowObject(UInt16 id) +{ + UInt16 obj_index; + + obj_index = FrmGetObjectIndex(FrmGetActiveForm(), id); + FrmShowObject(FrmGetActiveForm(), obj_index); +} + + + /*********************************************************************** + * + * FUNCTION: SetControls + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void SetControls(void) +{ + FieldPtr fldP; + Char *tmp; + FormPtr frmP; + + switch (audioState) + { + case audioStateNoVolume : + HideObject(MainPlayButton); + HideObject(MainPauseButton); + HideObject(MainRecordButton); + HideObject(MainStopButton); + HideObject(MainProgressSliderControl); + ShowObject(MainCardNotFoundLabel); + HideObject(MainProgressField); + break; + case audioStateNoFile : + HideObject(MainPlayButton); + HideObject(MainPauseButton); + canRecord ? ShowObject(MainRecordButton) : HideObject(MainRecordButton); + HideObject(MainStopButton); + HideObject(MainProgressSliderControl); + HideObject(MainCardNotFoundLabel); + HideObject(MainProgressField); + break; + case audioStateOpen : + ShowObject(MainPlayButton); + ShowObject(MainPauseButton); + canRecord ? ShowObject(MainRecordButton) : HideObject(MainRecordButton); + ShowObject(MainStopButton); + ShowObject(MainProgressSliderControl); + HideObject(MainCardNotFoundLabel); + HideObject(MainProgressField); + break; + case audioStatePlaying : + HideObject(MainPlayButton); + ShowObject(MainPauseButton); + HideObject(MainRecordButton); + ShowObject(MainStopButton); + ShowObject(MainProgressSliderControl); + HideObject(MainCardNotFoundLabel); + HideObject(MainProgressField); + break; + case audioStateRecording : + HideObject(MainPlayButton); + HideObject(MainPauseButton); + HideObject(MainRecordButton); + ShowObject(MainStopButton); + HideObject(MainProgressSliderControl); + HideObject(MainCardNotFoundLabel); + frmP = FrmGetActiveForm(); + ShowObject(MainProgressField); + fldP = (FieldPtr)GetObjectPtr(MainProgressField); + if ((tmp = FldGetTextPtr(fldP)) != NULL) + MemPtrFree(tmp); + tmp = (Char *)MemPtrNew(10); + StrCopy(tmp, "00:00"); + FldSetTextPtr(fldP, tmp); + FldDrawField(fldP); + break; + } +} + + /*********************************************************************** + * + * FUNCTION: HandlePlayButton + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void HandlePlayButton(void) +{ + Err retval; + + if (audioState != audioStateOpen) + return; + + audioState = audioStatePlaying; + SetControls(); + if ((retval = WavePlay()) == errNone) + audioState = audioStateOpen; + SetControls(); + + if (retval != errNone) + ErrAlert(retval); +} + +/*********************************************************************** + * + * FUNCTION: HandlePauseButton + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void HandlePauseButton(void) +{ + if (audioState != audioStatePlaying) + return; + +/*------------------------------------------------------------------------ + * Note : There is no pause state. WavePlay() will return after call to + * WavePause(), which will put state into audioStateStop. + *----------------------------------------------------------------------*/ + WavePause(); +} + + /*********************************************************************** + * + * FUNCTION: HandleStopButton + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void HandleStopButton(void) +{ + WaveStop(); + SetSliderPercent(FrmGetActiveForm(), 0); +} + +/*********************************************************************** + * + * FUNCTION: HandleRecordButton + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void HandleRecordButton(void) +{ + Boolean savedLaunchedFlag = false; + Err retval; + + if (audioState == audioStatePlaying) + return; + + WaveClose(); + + if ((retval = WaveCreate(WAVE_FILE)) == errNone) + { + audioState = audioStateRecording; + SetControls(); + + if (launchedFromButton) + { + savedLaunchedFlag = true; + SndPlaySystemSound(sndInfo); + SysTaskDelay(8); + } + + retval = WaveRecord(); + + if (savedLaunchedFlag) + { + SndPlaySystemSound(sndInfo); + SysTaskDelay(10); + SndPlaySystemSound(sndInfo); + } + + WaveClose(); + + if (retval == errNone) + { + if (WaveOpen(WAVE_FILE) == errNone) + { + audioState = audioStateOpen; + SetSliderPercent(FrmGetActiveForm(), 0); + } + else + audioState = audioStateNoFile; + } + } + else + audioState = audioStateNoFile; + + if (retval != errNone) + ErrAlert(retval); + + SetSliderPercent(FrmGetActiveForm(), 0); + SetControls(); +} + + /*********************************************************************** + * + * FUNCTION: HandleProgress + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void HandleProgress(EventPtr eventP) +{ + FormPtr frmP; + FieldPtr fldP; + UInt8 percent; + UInt16 minutes, seconds; + + percent = eventP->tapCount; + minutes = eventP->screenX; + seconds = eventP->screenY; + + frmP = FrmGetActiveForm(); + + if (launchedFromButton) + { +/*------------------------------------------------------------------------ + * If user let go of the Aux button + *----------------------------------------------------------------------*/ + if (auxButtonPresent && ((KeyCurrentState() & keyBitAux) == 0)) + { + launchedFromButton = false; + WaveStop(); + SetSliderPercent(FrmGetActiveForm(), 0); + return; + } + } + + if (audioState == audioStatePlaying) + SetSliderPercent(frmP, percent); + else if (audioState == audioStateRecording) + { + Char *buf, *tmp; + + buf = (Char *)MemPtrNew(20); + StrPrintF(buf, "%02d:%02d", minutes, seconds); + fldP = (FieldPtr)GetObjectPtr(MainProgressField); + if ((tmp = FldGetTextPtr(fldP)) != NULL) + MemPtrFree(tmp); + FldSetTextPtr(fldP, buf); + FldDrawField(fldP); + } + + EvtResetAutoOffTimer(); +} + +/*********************************************************************** + * + * FUNCTION: HandleSliderControl + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void HandleSliderControl(EventPtr eventP) +{ + static Err retval; + + retval = WaveSeek(eventP->data.ctlSelect.value); // tapCount is percent + +} + + /*********************************************************************** + * + * FUNCTION: MainFormHandleVolumeMounted + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +void MainFormHandleVolumeMounted (Boolean draw) +{ + if (WaveOpen(WAVE_FILE) == errNone) + audioState = audioStateOpen; + else + audioState = audioStateNoFile; + + if (draw) + { + SetSliderPercent(FrmGetActiveForm(), 0); + SetControls(); + FrmDrawForm(FrmGetActiveForm()); + } +} + +/*********************************************************************** + * + * FUNCTION: MainFormHandleVolumeUnmounted + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: Nothing + * + ***********************************************************************/ +void MainFormHandleVolumeUnmounted(Boolean draw) +{ + audioState = audioStateNoVolume; + + if (draw) + { + SetControls(); + FrmDrawForm(FrmGetActiveForm()); + } +} + + /*********************************************************************** + * + * FUNCTION: MainFormResize + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static void MainFormResize(FormPtr frmP, Boolean draw) +{ + Coord x, y; + Coord y_diff; + RectangleType r; + +/*------------------------------------------------------------------------ + * Get the new extent + *----------------------------------------------------------------------*/ + WinGetDisplayExtent(&x, &y); + +/*------------------------------------------------------------------------ + * Get the old extent + *----------------------------------------------------------------------*/ + FrmGetFormBounds(frmP, &r); + +/*------------------------------------------------------------------------ + * Calculate change, if none, do nothing + *----------------------------------------------------------------------*/ + y_diff = y - (r.topLeft.y + r.extent.y); + if (y_diff == 0) + return; + +/*------------------------------------------------------------------------ + * Resize the form + *----------------------------------------------------------------------*/ + r.extent.y += y_diff; + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + +/*------------------------------------------------------------------------ + * Move the buttons. + *----------------------------------------------------------------------*/ + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, MainPlayButton), y_diff, draw); + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, MainPauseButton), y_diff, draw); + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, MainRecordButton), y_diff, draw); + PrvMoveObject(frmP, FrmGetObjectIndex(frmP, MainStopButton), y_diff, draw); + + if (draw) + FrmDrawForm(frmP); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + ***********************************************************************/ +static void MainFormInit(FormPtr frmP) +{ + UInt32 features; + VolumeInfoType info; + +/*------------------------------------------------------------------------ + * Check to see if we were started using the Aux Button + *----------------------------------------------------------------------*/ + if (auxButtonPresent && ((KeyCurrentState() & keyBitAux) != 0)) + { + EventType new_event; + + new_event.eType = recordStartEvent; + EvtAddEventToQueue(&new_event); + launchedFromButton = true; + } + else + launchedFromButton = false; + + if (vgaPresent) + { + VgaFormModify(frmP, vgaFormModify160To240); + MainFormResize(frmP, false); + } + +/*------------------------------------------------------------------------ + * Check to see if unit has record capability + *----------------------------------------------------------------------*/ + AudioGetSupportedFeatures(&features); + + if (features & audioFtrRecordWave) + canRecord = true; + else + canRecord = false; + + WaveInit(); + + if (VFSVolumeInfo(VOLUME_REF_NUM, &info) == errNone) + { + if (WaveOpen(WAVE_FILE) == errNone) + { + audioState = audioStateOpen; + SetSliderPercent(FrmGetActiveForm(), 0); + } + else + audioState = audioStateNoFile; + } + else + audioState = audioStateNoVolume; + + SetControls(); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + UInt16 formID; + FormPtr frmP; + VgaScreenModeType screenMode; + VgaRotateModeType rotateMode; + + formID = (FrmGetFormId (FrmGetActiveForm ())); + + switch (command) + { + case MainOptionsAboutExampleJ: + MenuEraseStatus(0); + if (vgaPresent) + { + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenModeScaleToFit, rotateMode); + } + frmP = FrmInitForm (AboutForm); + FrmDoDialog (frmP); // Display the About Box. + FrmDeleteForm (frmP); + if (vgaPresent) + VgaSetScreenMode(screenMode, rotateMode); + handled = true; + break; + } + + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + ***********************************************************************/ +Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + frmP = FrmGetActiveForm(); + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case ctlSelectEvent : + switch(eventP->data.ctlSelect.controlID) + { + case MainPlayButton : + HandlePlayButton(); + handled = true; + break; + case MainPauseButton : + HandlePauseButton(); + handled = true; + break; + case MainStopButton : + HandleStopButton(); + handled = true; + break; + case MainRecordButton : + HandleRecordButton(); + handled = true; + break; + case MainProgressSliderControl : + HandleSliderControl(eventP); + handled = true; + break; + + } + break; + case frmOpenEvent: + MainFormInit(frmP); + FrmDrawForm (frmP); + handled = true; + break; + + case displayExtentChangedEvent : + MainFormResize(frmP, true); + break; + +/*------------------------------------------------------------------------ + * Check to see if a card was removed or inserted while we were not the + * active form. + *----------------------------------------------------------------------*/ + case winEnterEvent : + if (cardChangedOccurred) + { + SetControls(); + MainFormResize(frmP, true); + cardChangedOccurred = false; + } + break; + + case frmCloseEvent : + WaveClose(); + handled = true; + break; + + case recordStartEvent : + HandleRecordButton(); + break; + + case audioProgressEvent : + HandleProgress(eventP); + handled = true; + break; + + default: + break; + } + return(handled); +} + + diff --git a/handera-sdk-105/examples/ExampleJ/Src/MainForm.h b/handera-sdk-105/examples/ExampleJ/Src/MainForm.h new file mode 100644 index 0000000..33107f0 --- /dev/null +++ b/handera-sdk-105/examples/ExampleJ/Src/MainForm.h @@ -0,0 +1,19 @@ +/****************************************************************************** + * + * File: MainForm.h + * + * Project : Example J + * + *****************************************************************************/ +#ifndef _MAINFORM_H_ +#define _MAINFORM_H_ + +#include + +Boolean MainFormHandleEvent (EventPtr eventP); +void MainFormHandleVolumeMounted (Boolean draw); +void MainFormHandleVolumeUnmounted(Boolean draw); + +#endif + + diff --git a/handera-sdk-105/examples/ExampleJ/Src/STARTER.H b/handera-sdk-105/examples/ExampleJ/Src/STARTER.H new file mode 100644 index 0000000..fecce7f --- /dev/null +++ b/handera-sdk-105/examples/ExampleJ/Src/STARTER.H @@ -0,0 +1,23 @@ +/****************************************************************************** + * + * File: Starter.h + * + * Project : Example J + * + *****************************************************************************/ +#ifndef _STARTER_H_ +#define _STARTER_H_ + +/*********************************************************************** + * + * Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_J' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +#endif + + diff --git a/handera-sdk-105/examples/ExampleJ/Src/Wave.c b/handera-sdk-105/examples/ExampleJ/Src/Wave.c new file mode 100644 index 0000000..c207f3c --- /dev/null +++ b/handera-sdk-105/examples/ExampleJ/Src/Wave.c @@ -0,0 +1,202 @@ +/****************************************************************************** + * + * File: wave.c + * + * Project : Example 7 + * + *****************************************************************************/ + +#include +#include +#include "Audio.h" +#include "Wave.h" + +static Err WriteCallback(void *dataP, UInt32 offset, UInt32 *sizeP, void *userDataP); +static Err ReadCallback (void *dataP, UInt32 offset, UInt32 *sizeP, void *userDataP); + +static FileRef fd; +static AudioFormatType format; //format of current wave file. +static Boolean wave_open; + +/*-------------------------------------------------------------------------- + * Function : WaveInit() + * Description : + * Params : + * Returns : + *--------------------------------------------------------------------------*/ +void WaveInit(void) +{ + wave_open = false; +} + + /*-------------------------------------------------------------------------- + * Function : WaveOpen() + * Description : + * Params : + * Returns : + *--------------------------------------------------------------------------*/ +Err WaveOpen(char *filename) +{ + Err retval; + + if ((retval = VFSFileOpen(VOLUME_REF_NUM, filename, vfsModeRead, &fd)) != errNone) + return(retval); + + retval = AudioOpenWave(&format, ReadCallback, &fd); + + if (retval != 0) + VFSFileClose(fd); + else + wave_open = true; + + return(retval); +} + +/*-------------------------------------------------------------------------- + * Function : WaveClose() + * Description : + * Params : + * Returns : + *--------------------------------------------------------------------------*/ +void WaveClose(void) +{ + if (!wave_open) + return; + + VFSFileClose(fd); + AudioCloseWave(); + wave_open = false; +} + + /*-------------------------------------------------------------------------- + * Function : WaveCreate() + * Description : + * Params : + * Returns : + *--------------------------------------------------------------------------*/ +Err WaveCreate(char *filename) +{ + Err retval; + AudioFormatType record_format; //format of current wave file. + +/*------------------------------------------------------------------------ + * Currently, this is the only format that is supported. + *----------------------------------------------------------------------*/ + record_format.samplesPerSecond = 8000; + record_format.bitsPerSample = 8; + record_format.channels = 1; + + if ((retval = VFSFileOpen(VOLUME_REF_NUM, filename, vfsModeReadWrite | vfsModeCreate | vfsModeTruncate, &fd)) != errNone) + return(retval); + + retval = AudioCreateWave(&record_format, WriteCallback, &fd); + + if (retval != 0) + VFSFileClose(fd); + else + wave_open = true; + + return(retval); +} + + +/*-------------------------------------------------------------------------- + * Function : WavePlay() + * Description : + * Params : + * Returns : + *--------------------------------------------------------------------------*/ +Err WavePlay(void) +{ + return(AudioPlayData()); +} + +/*-------------------------------------------------------------------------- + * Function : WavePause() + * Description : + * Params : + * Returns : + *--------------------------------------------------------------------------*/ +Err WavePause(void) +{ + return(AudioPause()); +} + + + /*-------------------------------------------------------------------------- + * Function : WaveRecord() + * Description : + * Params : + * Returns : + *--------------------------------------------------------------------------*/ +Err WaveRecord(void) +{ + return(AudioRecordData()); +} + +/*-------------------------------------------------------------------------- + * Function : WaveStop() + * Description : + * Params : + * Returns : + *--------------------------------------------------------------------------*/ +Err WaveStop(void) +{ + Err retval; + + if ((retval = AudioPause()) == errNone) + return(WaveSeek(0)); + return(retval); +} + +/*-------------------------------------------------------------------------- + * Function : WaveSeek() + * Description : + * Params : + * Returns : + *--------------------------------------------------------------------------*/ +Err WaveSeek(UInt16 percent) +{ + return(AudioSeekPercent(percent)); +} + + + /*-------------------------------------------------------------------------- + * Function : WriteCallback() + * Description : + * Params : userDataP - points to file handle + * Returns : + *--------------------------------------------------------------------------*/ +static Err WriteCallback(void *dataP, UInt32 offset, UInt32 *sizeP, void *userDataP) +{ + Err retval = 0; + + retval = VFSFileSeek(*((FileRef *)userDataP), vfsOriginBeginning, offset); + + if ((retval == errNone) || (retval == vfsErrFileEOF)) + retval = VFSFileWrite(*((FileRef *)userDataP), *sizeP, dataP, sizeP); + + return(retval); +} + +/*-------------------------------------------------------------------------- + * Function : ReadCallback() + * Description : + * Params : + * Returns : + *--------------------------------------------------------------------------*/ +static Err ReadCallback(void *dataP, UInt32 offset, UInt32 *sizeP, void *userDataP) +{ + Err retval = 0; + + if ((retval = VFSFileSeek(*((FileRef *)userDataP), vfsOriginBeginning, offset)) != errNone) + return(retval); + + retval = VFSFileRead(*((FileRef *)userDataP), *sizeP, dataP, sizeP); + + return(retval); +} + + + + diff --git a/handera-sdk-105/examples/ExampleJ/Src/Wave.h b/handera-sdk-105/examples/ExampleJ/Src/Wave.h new file mode 100644 index 0000000..ee3a063 --- /dev/null +++ b/handera-sdk-105/examples/ExampleJ/Src/Wave.h @@ -0,0 +1,27 @@ +/**************************************************************************** + * File : Wave.h + * Date : 8-30-00 + * Description : + ****************************************************************************/ +#ifndef _WAVE_H_ +#define _WAVE_H_ + +/*------------------------------------------------------------------------ + * Hard code to first volume for this example, actual apps need to iterate + * through all the volumes. + *----------------------------------------------------------------------*/ +#define VOLUME_REF_NUM 1 + +void WaveInit (void); +Err WaveOpen (char *filename); +Err WaveCreate(char *filename); +void WaveClose (void); +Err WavePlay (void); +Err WavePause (void); +Err WaveRecord(void); +Err WaveStop (void); +Err WaveSeek (UInt16 percent); + +#endif + + diff --git a/handera-sdk-105/examples/ExampleJ/Src/starter.c b/handera-sdk-105/examples/ExampleJ/Src/starter.c new file mode 100644 index 0000000..2652b3d --- /dev/null +++ b/handera-sdk-105/examples/ExampleJ/Src/starter.c @@ -0,0 +1,371 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project : Example J + * + *****************************************************************************/ + +#include +#include +#include +#include "StarterRsc.h" + +#include "Vga.h" +#include "Audio.h" +#include "TrgChars.h" +#include "MainForm.h" +#include "starter.h" + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ +typedef StarterAppInfoType* StarterAppInfoPtr; + +Boolean vgaPresent; +Boolean audioPresent; +Boolean auxButtonPresent; +Boolean cardChangedOccurred; + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + + /*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + /*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + /*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + + /*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + UInt32 version, keys; + UInt16 cardNo; + LocalID appID; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + +/*------------------------------------------------------------------------ + * Verify system has VFS Manager + *----------------------------------------------------------------------*/ + if (FtrGet(sysFileCVFSMgr, vfsFtrIDVersion, &version) != errNone) + { + FrmAlert(VfsExtNotFoundAlert); + return(-1); + } + +/*------------------------------------------------------------------------ + * Make sure Audio Extension is present + *----------------------------------------------------------------------*/ + if (_TRGAudioFeaturePresent(&version)) + audioPresent = true; + else + { + audioPresent = false; + FrmAlert(AudioExtNotFoundAlert); + return(-1); + } + +/*------------------------------------------------------------------------ + * Check for an Aux Button + *----------------------------------------------------------------------*/ + if (_TRGKeyFeaturePresent(&keys) && (keys & keyBitAux)) + auxButtonPresent = true; + else + auxButtonPresent = false; + +/*------------------------------------------------------------------------ + * Check to see if VGA extension present + *----------------------------------------------------------------------*/ + if (_TRGVGAFeaturePresent(&version)) + vgaPresent = true; + else + vgaPresent = false; + +/*------------------------------------------------------------------------ + * Register for Card Removal/Insertion notifications + *----------------------------------------------------------------------*/ + SysCurAppDatabase(&cardNo, &appID); + SysNotifyRegister(0, appID, sysNotifyVolumeMountedEvent, NULL, sysNotifyNormalPriority, NULL); + SysNotifyRegister(0, appID, sysNotifyVolumeUnmountedEvent, NULL, sysNotifyNormalPriority, NULL); + + cardChangedOccurred = false; + + return(errNone); +} + + /*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + LocalID appID; + UInt16 cardNo; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Unregister for Card Removal/Insertions + *----------------------------------------------------------------------*/ + SysCurAppDatabase(&cardNo, &appID); + SysNotifyUnregister(0, appID, sysNotifyVolumeMountedEvent, sysNotifyNormalPriority); + SysNotifyUnregister(0, appID, sysNotifyVolumeUnmountedEvent, sysNotifyNormalPriority); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + + /*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + Err error; + Boolean draw; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + if ((error = AppStart()) != errNone) + return(error); + + if (vgaPresent) + VgaSetScreenMode(screenMode1To1, rotateModeNone); + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + + case sysAppLaunchCmdNotify : // HandEra popup silk screen + switch (((SysNotifyParamType *)cmdPBP)->notifyType) + { + case sysNotifyVolumeMountedEvent : + if ((FrmGetActiveFormID() == MainForm) && FrmVisible(FrmGetActiveForm())) + draw = true; + else + { + draw = false; + cardChangedOccurred = true; + } + MainFormHandleVolumeMounted(draw); + break; + case sysNotifyVolumeUnmountedEvent : + if ((FrmGetActiveFormID() == MainForm) && FrmVisible(FrmGetActiveForm())) + draw = true; + else + { + draw = false; + cardChangedOccurred = true; + } + MainFormHandleVolumeUnmounted(draw); + break; + } + break; + + default: + break; + + } + return(errNone); +} + + + /*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} + diff --git a/handera-sdk-105/examples/ExampleJ/StarterRsc.h b/handera-sdk-105/examples/ExampleJ/StarterRsc.h new file mode 100644 index 0000000..90e7123 --- /dev/null +++ b/handera-sdk-105/examples/ExampleJ/StarterRsc.h @@ -0,0 +1,84 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 9:23:56 AM on Tuesday, April 17, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleJ\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleJ" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) +#define MainPlayButton 1001 //(Left Origin = 2, Top Origin = 138, Width = 31, Height = 18, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Large) +#define MainRecordButton 1002 //(Left Origin = 78, Top Origin = 138, Width = 46, Height = 18, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Large) +#define MainProgressSliderControl 1003 //(Left Origin = 10, Top Origin = 53, Width = 140, Height = 30, Usable = 1, Initial Value = 0, Minimum Value = 0, Maximum Value = 100, Page Jump Amount = 10, Thumb Bitmap = 1700, Background Bitmap = 1800) +#define MainStopButton 1004 //(Left Origin = 127, Top Origin = 138, Width = 32, Height = 18, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Large) +#define MainPauseButton 1005 //(Left Origin = 37, Top Origin = 138, Width = 37, Height = 18, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Large) +#define MainCardNotFoundLabel 1006 //(Left Origin = 42, Top Origin = 70, Usable = 1, Font = Bold) +#define MainProgressField 1007 //(Left Origin = 68, Top Origin = 34, Width = 50, Height = 20, Usable = 1, Editable = 0, Underline = 0, Single Line = 1, Dynamic Size = 0, Left Justified = 1, Max Characters = 80, Font = Bold, Auto Shift = 0, Has Scroll Bar = 0, Numeric = 0) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutTitleLabel 1102 //(Left Origin = 52, Top Origin = 23, Usable = 1, Font = Large) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: Talt 1000 +#define AudioExtNotFoundAlert 1000 +#define AudioExtNotFoundOK 0 + +// Resource: Talt 1100 +#define VfsExtNotFoundAlert 1100 +#define VfsExtNotFoundOK 0 + +// Resource: MBAR 1000 +#define MainFormMenuBar 1000 + +// Resource: MENU 1000 +#define MainOptionsMenu 1000 +#define MainOptionsAboutExampleJ 1000 + +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: PICT 1400 +#define VGABigIconBitmap 1400 +// Resource: PICT 1500 +#define VGASmallIconBitmap 1500 +// Resource: PICT 1600 +#define VGABigIconInvertedBitmap 1600 +// Resource: PICT 1700 +#define ThumbBitmap 1700 +// Resource: PICT 1800 +#define SliderLineBitmap 1800 +// Resource: PICT 5896 +#define VGASliderLineBitmap 5896 +// Resource: PICT 5796 +#define VGAThumbBitmap 5796 +// Resource: taif 2002 +#define VGABigIconInvertedAppIconFamily 2002 + +// Resource: taif 2001 +#define VGASmallIconAppIconFamily 2001 + +// Resource: taif 2000 +#define VGABigIconAppIconFamily 2000 + +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 diff --git a/handera-sdk-105/examples/ExampleK/ExampleK.mcp b/handera-sdk-105/examples/ExampleK/ExampleK.mcp new file mode 100644 index 0000000..5e34120 Binary files /dev/null and b/handera-sdk-105/examples/ExampleK/ExampleK.mcp differ diff --git a/handera-sdk-105/examples/ExampleK/Rsc/HandEra.r b/handera-sdk-105/examples/ExampleK/Rsc/HandEra.r new file mode 100644 index 0000000..371e069 --- /dev/null +++ b/handera-sdk-105/examples/ExampleK/Rsc/HandEra.r @@ -0,0 +1,29 @@ +/*********************************************************************** + * + * Copyright (c) 1999-2001, TRG, All Rights Reserved + * + * PROJECT: HandEra 330 + * + * FILE: HandEra.r + * + * DESCRIPTION: + * + * AUTHOR: John Ehm + * + * DATE: 01/17/01 + * + **********************************************************************/ + + +type 'sKst' { + //Currently no data is stored in resource, need dummy otherwise + //resource is not linked in + unsigned longint; +}; + + +resource 'sKst' (1000, "HandEra Aware") +{ + 0x00000000; + +}; diff --git a/handera-sdk-105/examples/ExampleK/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleK/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..40a4ce2 Binary files /dev/null and b/handera-sdk-105/examples/ExampleK/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleK/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleK/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleK/Src/starter.c b/handera-sdk-105/examples/ExampleK/Src/starter.c new file mode 100644 index 0000000..b6452e9 --- /dev/null +++ b/handera-sdk-105/examples/ExampleK/Src/starter.c @@ -0,0 +1,537 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project : Example K + * + *****************************************************************************/ + +#include +#include "StarterRsc.h" + +#include "vga.h" + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +typedef StarterAppInfoType* StarterAppInfoPtr; + +Boolean vgaPresent = false; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_K' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ + + /*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + + +/*********************************************************************** + * + * FUNCTION: HandleAlarm() + * + * DESCRIPTION: + * + * PARAMETERS: None + * + * RETURNED: Nothing + * + ***********************************************************************/ +static void HandleAlarm(void) +{ + VgaScreenStateType saveScreenState; + FormActiveStateType stateP; + UInt32 version; + FormPtr frmP; + Boolean vga_present; + + vga_present = _TRGVGAFeaturePresent(&version); + +/*------------------------------------------------------------------------ + * You must set the screen mode before the form is loaded. +--------------------------------------------------------------------*/ + FrmActiveState(&stateP, true); //Save the active form state + +/*------------------------------------------------------------------------ + * Load the Alarm Form. + *----------------------------------------------------------------------*/ + frmP = FrmInitForm (AlarmForm); + + if(vga_present) + { +/*------------------------------------------------------------------------ + * Get and save the current screen state. + *----------------------------------------------------------------------*/ + VgaSaveScreenState(&saveScreenState); + +/*------------------------------------------------------------------------ + * If the screen is rotated 0 or 180 degrees then modify the alarm to fit the + * entire screen. + *----------------------------------------------------------------------*/ + if ((saveScreenState.rotate == rotateModeNone) || + (saveScreenState.rotate == rotateMode180)) + { + VgaFormModify(frmP, vgaFormModify160To240); + } +/*------------------------------------------------------------------------ + * Set the screen mode to 1To1. Keep the same rotation. + *----------------------------------------------------------------------*/ + VgaSetScreenMode(screenMode1To1, saveScreenState.rotate); + } + +/*------------------------------------------------------------------------ + * Display the Alarm + *----------------------------------------------------------------------*/ + FrmDoDialog (frmP); + FrmDeleteForm (frmP); + +/*------------------------------------------------------------------------ + * Restore the VGA screen state + *----------------------------------------------------------------------*/ + if(vga_present) + VgaRestoreScreenState(&saveScreenState); + +/*------------------------------------------------------------------------ + * Restore the active form state. + *----------------------------------------------------------------------*/ + FrmActiveState(&stateP, false); + +} + +/*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + ***********************************************************************/ +static void MainFormInit(FormPtr frmP) +{ + if(vgaPresent) + VgaFormModify(frmP, vgaFormModify160To240); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + UInt16 formID; + FormPtr frmP, aboutFrmP; + VgaScreenModeType screenMode; + VgaRotateModeType rotateMode; + + frmP = FrmGetActiveForm(); + formID = FrmGetFormId (frmP); + + switch (command) + { + case MainOptionsAboutExampleK: + MenuEraseStatus(0); + if (vgaPresent) + { + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenModeScaleToFit, rotateMode); + } + aboutFrmP = FrmInitForm (AboutForm); + FrmDoDialog (aboutFrmP); // Display the About Box. + FrmDeleteForm (aboutFrmP); + if (vgaPresent) + VgaSetScreenMode(screenMode, rotateMode); + handled = true; + break; + } + + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit(frmP); + FrmDrawForm (frmP); + handled = true; + break; + + case ctlSelectEvent: + switch (eventP->data.ctlSelect.controlID) + { + UInt16 cardN; + LocalID dbID; + + case MainSetAlarmButton: +/*------------------------------------------------------------------------ + * Set the alarm to 10 seconds from now. + *----------------------------------------------------------------------*/ + if(SysCurAppDatabase(&cardN, &dbID) == 0) + AlmSetAlarm (cardN, dbID, 1, TimGetSeconds() + 10, true); + + handled = true; + break; + } + + default: + break; + } + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + +/*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + + /*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: Get the current application's preferences. + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + UInt32 version; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + +/*------------------------------------------------------------------------ + * Check for VGA Extension + *----------------------------------------------------------------------*/ + if (_TRGVGAFeaturePresent(&version)) + vgaPresent = true; + else + vgaPresent = false; + + return(errNone); +} + +/*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + + /*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + Err error; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + if ((error = AppStart()) != errNone) + return(error); + +/*------------------------------------------------------------------------ + * You must set the screen mode before the form is loaded. + *----------------------------------------------------------------------*/ + if (vgaPresent) + VgaSetScreenMode(screenMode1To1, rotateModeNone); + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + + case sysAppLaunchCmdDisplayAlarm: + HandleAlarm(); + break; + + default: + break; + + } + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} diff --git a/handera-sdk-105/examples/ExampleK/StarterRsc.h b/handera-sdk-105/examples/ExampleK/StarterRsc.h new file mode 100644 index 0000000..b2a7a10 --- /dev/null +++ b/handera-sdk-105/examples/ExampleK/StarterRsc.h @@ -0,0 +1,70 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 8:40:08 AM on Tuesday, March 27, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleK\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleK" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) +#define MainSetAlarmButton 1001 //(Left Origin = 54, Top Origin = 75, Width = 50, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) +#define MainUnnamed1002Label 1002 //(Left Origin = 4, Top Origin = 39, Usable = 1, Font = Standard) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutText1Label 1103 //(Left Origin = 20, Top Origin = 54, Usable = 1, Font = Standard) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: tFRM 1200 +#define AlarmForm 1200 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AlarmUnnamed1201Label 1201 //(Left Origin = 54, Top Origin = 25, Usable = 1, Font = Bold 12) +#define AlarmText1Label 1203 //(Left Origin = 20, Top Origin = 58, Usable = 1, Font = Standard) +#define AlarmOKButton 1205 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: MBAR 1000 +#define PalmMenuBar 1000 + +// Resource: MENU 1000 +#define MainOptionsMenu 1000 +#define MainOptionsAboutExampleK 1000 + +// Resource: PICT 1600 +#define VGABigIconInvertedBitmap 1600 +// Resource: PICT 1500 +#define VGASmallIconBitmap 1500 +// Resource: PICT 1400 +#define VGABigIconBitmap 1400 +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: taif 2002 +#define VGABigIconInvertedAppIconFamily 2002 + +// Resource: taif 2001 +#define VGASmallIconAppIconFamily 2001 + +// Resource: taif 2000 +#define VGABigIconAppIconFamily 2000 + +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 diff --git a/handera-sdk-105/examples/ExampleL/ExampleL.mcp b/handera-sdk-105/examples/ExampleL/ExampleL.mcp new file mode 100644 index 0000000..3f49c80 Binary files /dev/null and b/handera-sdk-105/examples/ExampleL/ExampleL.mcp differ diff --git a/handera-sdk-105/examples/ExampleL/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleL/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..60dc574 Binary files /dev/null and b/handera-sdk-105/examples/ExampleL/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleL/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleL/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleL/Src/starter.c b/handera-sdk-105/examples/ExampleL/Src/starter.c new file mode 100644 index 0000000..11288f5 --- /dev/null +++ b/handera-sdk-105/examples/ExampleL/Src/starter.c @@ -0,0 +1,597 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project : Example L + * + *****************************************************************************/ + +#include +#include "StarterRsc.h" + +#include "Vga.h" +#include "TrgRsc.h" + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +typedef StarterAppInfoType* StarterAppInfoPtr; + +typedef struct +{ + LocalID dbID; + UInt32 creator; +} db_type; + + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_L' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +#define appLrgIconID 1000 +#define appSmallIconID 1001 + +#define maxDbs 50 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ + +/*********************************************************************** + * + * Local variables + * + ***********************************************************************/ +static Boolean vgaPresent = false; +static db_type db[maxDbs]; +static Int16 numDbs; + + + /*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + + + /*********************************************************************** + * + * FUNCTION: LoadDbs + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static void LoadDbs(void) +{ + DmSearchStateType search; + LocalID dbID; + UInt32 creator; + Err err; + + err = DmGetNextDatabaseByTypeCreator(true, &search, 'appl', 0, true, 0, &dbID); + + for (numDbs = 0; (err == errNone) && (numDbs < maxDbs); numDbs++) + { + + DmDatabaseInfo(0, dbID, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &creator); + + db[numDbs].dbID = dbID; + db[numDbs].creator = creator; + + err = DmGetNextDatabaseByTypeCreator(false, &search, 'appl', 0, true, 0, &dbID); + } +} + + +/*********************************************************************** + * + * FUNCTION: DrawLargeVgaIcon + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static void DrawLargeVgaIcon(LocalID dbID, UInt32 creator, Coord x, Coord y) +{ + DmOpenRef appDB = NULL; + BitmapPtr iconP = NULL; + MemHandle iconH = NULL; + +/*------------------------------------------------------------------------- + * First look for icons in VGA Resource Database, if not found look in the + * app itself. + *------------------------------------------------------------------------*/ + if ((appDB = DmOpenDatabaseByTypeCreator(vgaResourceDbType, creator, dmModeReadOnly)) == NULL) + appDB = DmOpenDatabase(0, dbID, dmModeReadOnly); + + if(appDB != NULL) + { +/*------------------------------------------------------------------------- + * If 32x32 exists, use it, otherwise expand the 22x22 icon + *------------------------------------------------------------------------*/ + if ((iconH = DmGet1Resource(iconType, vgaAppIconID)) != NULL) + { + iconP = MemHandleLock(iconH); + WinDrawBitmap(iconP, x, y); + MemHandleUnlock(iconH); + DmReleaseResource(iconH); + } + else if ((iconH = DmGet1Resource(iconType, appLrgIconID)) != NULL) + { + iconP = MemHandleLock(iconH); + VgaWinDrawBitmapExpanded(iconP, x, y); + MemHandleUnlock(iconH); + DmReleaseResource(iconH); + } + DmCloseDatabase(appDB); + } + +/*------------------------------------------------------------------------ + * Draw Default Icon - Left as an exercise for the reader + *----------------------------------------------------------------------*/ +} + + + /*********************************************************************** + * + * FUNCTION: MainFormResize + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static void MainFormResize(FormPtr frmP, Boolean draw) +{ + Coord x,y; + RectangleType r; + + WinGetDisplayExtent(&x, &y); + RctSetRectangle(&r, 0, 0, x, y); + + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); +} + + +/*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + ***********************************************************************/ +static void MainFormInit(FormPtr frmP) +{ + if (vgaPresent) + { + VgaFormModify(frmP, vgaFormModify160To240); + MainFormResize(frmP, false); + } + + LoadDbs(); +} + +/*********************************************************************** + * + * FUNCTION: MainFormDrawIcons + * + * DESCRIPTION: Draw the first n icons on the screen. Do not worry about + * cosmetic appearance. + * + * PARAMETERS: + * + * RETURNED: Nohting + * + ***********************************************************************/ +static void MainFormDrawIcons(void) +{ + Int16 index = 0; + Coord x,y; + + for (y = 30; y < 210; y+=50) + { + for (x = 10; x < 210; x += 50) + { + DrawLargeVgaIcon(db[index].dbID, db[index].creator, x, y); + index++; + + if (index == numDbs) + return; + } + } +} + + + /*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + UInt16 formID; + FormPtr frmP; + VgaScreenModeType screenMode; + VgaRotateModeType rotateMode; + + formID = (FrmGetFormId (FrmGetActiveForm ())); + + switch (command) + { + case MainOptionsAboutExampleL: + MenuEraseStatus(0); + if (vgaPresent) + { + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenModeScaleToFit, rotateMode); + } + frmP = FrmInitForm (AboutForm); + FrmDoDialog (frmP); // Display the About Box. + FrmDeleteForm (frmP); + if (vgaPresent) + VgaSetScreenMode(screenMode, rotateMode); + handled = true; + break; + + } + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + ***********************************************************************/ +static Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit( frmP); + FrmDrawForm ( frmP); + MainFormDrawIcons(); + handled = true; + break; + + default: + break; + } + return(handled); +} + + + /*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + +/*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + + /*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: Get the current application's preferences. + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + UInt32 version; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + +/*------------------------------------------------------------------------ + * Check for VGA Extension + *----------------------------------------------------------------------*/ + if (_TRGVGAFeaturePresent(&version)) + vgaPresent = true; + else + { + FrmAlert(VgaNotFoundAlert); + vgaPresent = false; + return(-1); + } + + return(errNone); +} + +/*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + + /*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + Err error; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + if ((error = AppStart()) != errNone) + return(error); + + if (vgaPresent) + VgaSetScreenMode(screenMode1To1, rotateModeNone); + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + + default: + break; + + } + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} + diff --git a/handera-sdk-105/examples/ExampleL/StarterRsc.h b/handera-sdk-105/examples/ExampleL/StarterRsc.h new file mode 100644 index 0000000..aa7fe29 --- /dev/null +++ b/handera-sdk-105/examples/ExampleL/StarterRsc.h @@ -0,0 +1,66 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 7:19:48 AM on Saturday, March 24, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleL\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleL" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1000 +#define MainForm 1000 //(Left Origin = 0, Top Origin = 0, Width = 160, Height = 160, Usable = 1, Modal = 0, Save Behind = 0, Help ID = 0, Menu Bar ID = 1000, Default Button ID = 0) + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutTitleLabel 1102 //(Left Origin = 52, Top Origin = 23, Usable = 1, Font = Large) +#define AboutText1Label 1103 //(Left Origin = 23, Top Origin = 54, Usable = 1, Font = Standard) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: Talt 1000 +#define VgaNotFoundAlert 1000 +#define VgaNotFoundOK 0 + +// Resource: MBAR 1000 +#define MainMenuBar 1000 + +// Resource: MENU 1000 +#define MainOptionsMenu 1000 +#define MainOptionsAboutExampleL 1000 + +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: PICT 1400 +#define VGABigIconBitmap 1400 +// Resource: PICT 1500 +#define VGASmallIconBitmap 1500 +// Resource: PICT 1600 +#define VGABigIconInvertedBitmap 1600 +// Resource: taif 2002 +#define VGABigIconInvertedAppIconFamily 2002 + +// Resource: taif 2001 +#define VGASmallIconAppIconFamily 2001 + +// Resource: taif 2000 +#define VGABigIconAppIconFamily 2000 + +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 diff --git a/handera-sdk-105/examples/ExampleX/ExampleX.mcp b/handera-sdk-105/examples/ExampleX/ExampleX.mcp new file mode 100644 index 0000000..03b9ab4 Binary files /dev/null and b/handera-sdk-105/examples/ExampleX/ExampleX.mcp differ diff --git a/handera-sdk-105/examples/ExampleX/Rsc/Resource.frk/Starter.rsrc b/handera-sdk-105/examples/ExampleX/Rsc/Resource.frk/Starter.rsrc new file mode 100644 index 0000000..ba09137 Binary files /dev/null and b/handera-sdk-105/examples/ExampleX/Rsc/Resource.frk/Starter.rsrc differ diff --git a/handera-sdk-105/examples/ExampleX/Rsc/STARTER.R b/handera-sdk-105/examples/ExampleX/Rsc/STARTER.R new file mode 100644 index 0000000..551a036 --- /dev/null +++ b/handera-sdk-105/examples/ExampleX/Rsc/STARTER.R @@ -0,0 +1,26 @@ +#include "starter.rh" + +resource 'tFRM' (1000, "Main") { + 0, + 0, + 240, + 240, + usable, + notModal, + noSaveBehind, + 1000, + 0, + 1000, + 0, + { /* array ObjectArray: 1 elements */ + /* [1] */ + 1000, "tTTL" + } +}; + + + +data 'tTTL' (1000) { + $"4578 616d 706c 6558 00" +}; + diff --git a/handera-sdk-105/examples/ExampleX/Rsc/STARTER.RH b/handera-sdk-105/examples/ExampleX/Rsc/STARTER.RH new file mode 100644 index 0000000..9a2be74 --- /dev/null +++ b/handera-sdk-105/examples/ExampleX/Rsc/STARTER.RH @@ -0,0 +1 @@ +#define MainForm 1000 diff --git a/handera-sdk-105/examples/ExampleX/Rsc/Starter.rsrc b/handera-sdk-105/examples/ExampleX/Rsc/Starter.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/ExampleX/Src/starter.c b/handera-sdk-105/examples/ExampleX/Src/starter.c new file mode 100644 index 0000000..e8a261d --- /dev/null +++ b/handera-sdk-105/examples/ExampleX/Src/starter.c @@ -0,0 +1,625 @@ +/****************************************************************************** + * + * File: Starter.c + * + * Project: Example X + * + *****************************************************************************/ + +#include +#include "StarterRsc.h" +#include "starter.rh" //MainForm definition + +#include "Trg.h" +#include "Vga.h" +#include "Silk.h" + +/*********************************************************************** + * + * Entry Points + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Structures + * + ***********************************************************************/ +typedef struct +{ + UInt8 replaceme; +} StarterPreferenceType; + +typedef struct +{ + UInt8 replaceme; +} StarterAppInfoType; + +typedef StarterAppInfoType* StarterAppInfoPtr; + +FontID currentFont = stdFont; +Boolean vgaPresent = false; +Boolean screenChanged = false; + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define appFileCreator 'Ex_X' +#define appVersionNum 0x01 +#define appPrefID 0x00 +#define appPrefVersionNum 0x01 + +// Define the minimum OS version we support (2.0 for now). +#define ourMinVersion sysMakeROMVersion(2,0,0,sysROMStageRelease,0) + +/*********************************************************************** + * + * Internal Functions + * + ***********************************************************************/ +static void DrawHelloWorld(void); + + +/*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: This routine checks that a ROM version is meet your + * minimum requirement. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags that indicate if the application + * UI is initialized. + * + * RETURNED: error code or zero if rom is compatible + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Err RomVersionCompatible(UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + +/*------------------------------------------------------------------------ + * See if we're on in minimum required version of the ROM or later. + *----------------------------------------------------------------------*/ + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + +/*------------------------------------------------------------------------ + * Palm OS 1.0 will continuously relaunch this app unless we switch to + * another safe one. + *----------------------------------------------------------------------*/ + if (romVersion < ourMinVersion) + { + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + return sysErrRomIncompatible; + } + + return errNone; +} + + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void * GetObjectPtr(UInt16 objectID) +{ + FormPtr frmP; + + frmP = FrmGetActiveForm(); + return(FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, objectID))); +} + +/*********************************************************************** + * + * FUNCTION: MainFormResize + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void MainFormResize(FormPtr frmP, Boolean draw) +{ + Coord x,y; + RectangleType r; + + WinGetDisplayExtent(&x, &y); + RctSetRectangle(&r, 0, 0, x, y); + + frmP = FrmGetActiveForm(); + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + screenChanged = false; + + if (draw) + DrawHelloWorld(); +} + +/*********************************************************************** + * + * FUNCTION: DrawHelloWorld + * + * DESCRIPTION: This routine prints "Hello World" to the center of the + * window. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: void * + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void DrawHelloWorld(void) +{ + MemHandle resH; + BitmapPtr resP; + char *str = "Hello World"; + FontID savedFont; + Coord x, y, winWidth, winHeight; + FormPtr formP; + UInt8 *ptr; + + formP = FrmGetActiveForm(); + +/*------------------------------------------------------------------------ + * Lock the screen to remove flicker + *----------------------------------------------------------------------*/ + ptr = WinScreenLock(winLockCopy); + + FrmEraseForm(formP); + FrmDrawForm(formP); + + if (vgaPresent) + resH = DmGetResource(bitmapRsc, VGAGlobeBitmap); + else + resH = DmGetResource(bitmapRsc, GlobeBitmap); + ErrFatalDisplayIf(!resH, "Missing bitmap"); + resP = MemHandleLock(resH); + + WinGetDisplayExtent(&winWidth, &winHeight); + savedFont = FntSetFont(currentFont); + +/*------------------------------------------------------------------------ + * Draw the globe graphic + *----------------------------------------------------------------------*/ + x = (winWidth/2) - (resP->width/2); + y = (winHeight/2) - (resP->height/2); + WinDrawBitmap(resP, x, y); + +/*------------------------------------------------------------------------ + * Draw String below the globe + *----------------------------------------------------------------------*/ + x = (winWidth/2) - (FntCharsWidth(str, StrLen(str))/2); + y = y + resP->height + 5; + WinDrawChars(str, StrLen(str), x, y); + + FntSetFont(savedFont); + MemPtrUnlock(resP); + DmReleaseResource(resH); + + if (ptr) + WinScreenUnlock(); +} + + +/*********************************************************************** + * + * FUNCTION: MainFormInit + * + * DESCRIPTION: This routine initializes the MainForm form. + * + * PARAMETERS: frm - pointer to the MainForm form. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void MainFormInit(FormPtr frmP) +{ + currentFont = stdFont; + + if (vgaPresent) + { + currentFont = VgaBaseToVgaFont(currentFont); + MainFormResize(frmP, false); + } +} + + +/*********************************************************************** + * + * FUNCTION: MainFormDoCommand + * + * DESCRIPTION: This routine performs the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormDoCommand(UInt16 command) +{ + Boolean handled = false; + UInt16 formID; + FormPtr frmP; + FontID newFont; + VgaScreenModeType screenMode; + VgaRotateModeType rotateMode; + + formID = (FrmGetFormId (FrmGetActiveForm ())); + + switch (command) + { + case MainOptionsAboutExampleX: + MenuEraseStatus(0); + VgaGetScreenMode(&screenMode, &rotateMode); + VgaSetScreenMode(screenModeScaleToFit, rotateMode); + frmP = FrmInitForm (AboutForm); + FrmDoDialog (frmP); // Display the About Box. + FrmDeleteForm (frmP); + VgaSetScreenMode(screenMode, rotateMode); + handled = true; + break; + + case MainOptionsFont : + newFont = FontSelect(currentFont); + FrmEraseForm(FrmGetActiveForm ()); + currentFont = newFont; + handled = true; + break; + } + + FrmUpdateForm (formID, frmRedrawUpdateCode); + + return(handled); +} + +/*********************************************************************** + * + * FUNCTION: MainFormHandleEvent + * + * DESCRIPTION: This routine is the event handler for the + * "MainForm" of this application. + * + * PARAMETERS: eventP - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean MainFormHandleEvent(EventPtr eventP) +{ + Boolean handled = false; + FormPtr frmP; + + switch (eventP->eType) + { + case menuEvent: + return MainFormDoCommand(eventP->data.menu.itemID); + + case frmOpenEvent: + frmP = FrmGetActiveForm(); + MainFormInit( frmP); + FrmDrawForm ( frmP); + DrawHelloWorld(); + handled = true; + break; + + case frmUpdateEvent : + DrawHelloWorld(); + handled = true; + break; + + case winEnterEvent: + if (screenChanged && (FrmGetActiveFormID() == MainForm)) + MainFormResize(FrmGetActiveForm(), true); + break; + + default: + break; + } + return(handled); +} + + +/*********************************************************************** + * + * FUNCTION: AppHandleEvent + * + * DESCRIPTION: This routine loads form resources and set the event + * handler for the form loaded. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Boolean AppHandleEvent(EventPtr eventP) +{ + UInt16 formId; + FormPtr frmP; + + if (eventP->eType == frmLoadEvent) + { +/*------------------------------------------------------------------------ + * Load the form resource. + *----------------------------------------------------------------------*/ + formId = eventP->data.frmLoad.formID; + frmP = FrmInitForm(formId); + FrmSetActiveForm(frmP); +/*------------------------------------------------------------------------ + * Set the event handler for the form. The handler of the currently + * active form is called by FrmHandleEvent each time is receives an event. + *----------------------------------------------------------------------*/ + switch (formId) + { + case MainForm: + FrmSetEventHandler(frmP, MainFormHandleEvent); + break; + default: + ErrFatalDisplay("Invalid Form Load Event"); + break; + + } + return(true); + } + + return(false); +} + + +/*********************************************************************** + * + * FUNCTION: AppEventLoop + * + * DESCRIPTION: This routine is the event loop for the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppEventLoop(void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent(&event, evtWaitForever); + + if (! SysHandleEvent(&event)) + if (! MenuHandleEvent(0, &event, &error)) + if (! AppHandleEvent(&event)) + FrmDispatchEvent(&event); + + } while (event.eType != appStopEvent); +} + + +/*********************************************************************** + * + * FUNCTION: AppStart + * + * DESCRIPTION: Get the current application's preferences. + * + * PARAMETERS: nothing + * + * RETURNED: Err value 0 if nothing went wrong + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static Err AppStart(void) +{ + StarterPreferenceType prefs; + UInt16 prefsSize; + UInt32 version; + UInt16 cardNo; + LocalID appID; + +/*------------------------------------------------------------------------ + * Read the saved preferences / saved-state information. + *----------------------------------------------------------------------*/ + prefsSize = sizeof(StarterPreferenceType); + if (PrefGetAppPreferences(appFileCreator, appPrefID, &prefs, &prefsSize, true) != + noPreferenceFound) + { + } + +/*------------------------------------------------------------------------ + * Check for the VGA Extension + *----------------------------------------------------------------------*/ + if (_TRGVGAFeaturePresent(&version)) + vgaPresent = true; + else + { + FrmAlert(VgaNotFoundAlert); + vgaPresent = false; + return(-1); //some generic error for now + } + +/*------------------------------------------------------------------------ + * Register for silk screen change notifications. + * Note: You do not need to check for the presense of the silk extension to + * register for its notifications. If the silk extension is not present + * you simply will not receive any notifications. + *----------------------------------------------------------------------*/ + SysCurAppDatabase(&cardNo, &appID); + SysNotifyRegister(0, appID, trgNotifySilkEvent, NULL, sysNotifyNormalPriority, NULL); + + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: AppStop + * + * DESCRIPTION: Save the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static void AppStop(void) +{ + StarterPreferenceType prefs; + UInt16 cardNo; + LocalID appID; + +/*------------------------------------------------------------------------ + * Write the saved preferences / saved-state information. This data + * will be backed up during a HotSync. + *----------------------------------------------------------------------*/ + PrefSetAppPreferences (appFileCreator, appPrefID, appPrefVersionNum, + &prefs, sizeof (prefs), true); + +/*------------------------------------------------------------------------ + * Unregister for silk screen change notifications + *----------------------------------------------------------------------*/ + SysCurAppDatabase(&cardNo, &appID); + SysNotifyUnregister(cardNo, appID, trgNotifySilkEvent, sysNotifyNormalPriority); + +/*------------------------------------------------------------------------ + * Close all the open forms. + *----------------------------------------------------------------------*/ + FrmCloseAllForms (); +} + + +/*********************************************************************** + * + * FUNCTION: StarterPalmMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +static UInt32 StarterPalmMain(UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + Err error; + + if ((error = RomVersionCompatible (ourMinVersion, launchFlags)) != 0) + return (error); + + switch (cmd) + { + case sysAppLaunchCmdNormalLaunch: + error = AppStart(); + if (error) + return error; + + if (vgaPresent) + VgaSetScreenMode(screenMode1To1, rotateModeNone); + + FrmGotoForm(MainForm); + AppEventLoop(); + AppStop(); + break; + + case sysAppLaunchCmdNotify : // HandEra popup silk screen + if ( ((SysNotifyParamType *)cmdPBP)->notifyType == trgNotifySilkEvent) + { + if ((FrmGetActiveFormID() == MainForm) && FrmVisible(FrmGetActiveForm())) + MainFormResize(FrmGetActiveForm(), true); + else + screenChanged = true; + } + break; + + default: + break; + + } + return(errNone); +} + + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the application. + * + * PARAMETERS: cmd - word value specifying the launch code. + * cmdPB - pointer to a structure that is associated with the launch code. + * launchFlags - word value providing extra information about the launch. + * RETURNED: Result of launch + * + * REVISION HISTORY: + * + * + ***********************************************************************/ +UInt32 PilotMain( UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + return StarterPalmMain(cmd, cmdPBP, launchFlags); +} + diff --git a/handera-sdk-105/examples/ExampleX/StarterRsc.h b/handera-sdk-105/examples/ExampleX/StarterRsc.h new file mode 100644 index 0000000..33d31a6 --- /dev/null +++ b/handera-sdk-105/examples/ExampleX/StarterRsc.h @@ -0,0 +1,67 @@ +// Header generated by Constructor for Palm OS¨ 1.6 +// +// Generated at 3:50:42 PM on Wednesday, April 25, 2001 +// +// Generated for file: T:\TRGProd\StarKist\sw\sdk\cw\examples\ExampleX\Rsc\Starter.rsrc +// +// THIS IS AN AUTOMATICALLY GENERATED HEADER FILE FROM CONSTRUCTOR FOR PALM OS¨; +// - DO NOT EDIT - CHANGES MADE TO THIS FILE WILL BE LOST +// +// Palm App Name: "ExampleX" +// +// Palm App Version: "1.0" + + + +// Resource: tFRM 1100 +#define AboutForm 1100 //(Left Origin = 2, Top Origin = 2, Width = 156, Height = 156, Usable = 1, Modal = 1, Save Behind = 1, Help ID = 0, Menu Bar ID = 0, Default Button ID = 0) +#define AboutTitleLabel 1102 //(Left Origin = 61, Top Origin = 23, Usable = 1, Font = Large) +#define AboutText1Label 1103 //(Left Origin = 57, Top Origin = 58, Usable = 1, Font = Standard) +#define AboutText2Label 1104 //(Left Origin = 50, Top Origin = 104, Usable = 1, Font = Bold) +#define AboutOKButton 1105 //(Left Origin = 58, Top Origin = 133, Width = 40, Height = 12, Usable = 1, Anchor Left = 1, Frame = 1, Non-bold Frame = 1, Font = Standard) + + +// Resource: Talt 1001 +#define RomIncompatibleAlert 1001 +#define RomIncompatibleOK 0 + +// Resource: Talt 1000 +#define VgaNotFoundAlert 1000 +#define VgaNotFoundOK 0 + +// Resource: MBAR 1000 +#define MainFormMenuBar 1000 + +// Resource: MENU 1000 +#define MainOptionsMenu 1000 +#define MainOptionsFont 1000 +#define MainOptionsAboutExampleX 1001 + +// Resource: PICT 1200 +#define GlobeBitmap 1200 +// Resource: PICT 1100 +#define SmallIconBitmap 1100 +// Resource: PICT 1000 +#define BigIconBitmap 1000 +// Resource: PICT 1400 +#define VGABigIconBitmap 1400 +// Resource: PICT 1500 +#define VGASmallIconBitmap 1500 +// Resource: PICT 17584 +#define VGAGlobeBitmap 17584 +// Resource: PICT 1600 +#define VGABigIconInvertedBitmap 1600 +// Resource: taif 2002 +#define VGABigIconInvertedAppIconFamily 2002 + +// Resource: taif 2001 +#define VGASmallIconAppIconFamily 2001 + +// Resource: taif 2000 +#define VGABigIconAppIconFamily 2000 + +// Resource: taif 1001 +#define SmallIconAppIconFamily 1001 + +// Resource: taif 1000 +#define BigIconAppIconFamily 1000 diff --git a/handera-sdk-105/examples/Mail/Mail.mcp b/handera-sdk-105/examples/Mail/Mail.mcp new file mode 100644 index 0000000..e595c14 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Mail.mcp differ diff --git a/handera-sdk-105/examples/Mail/Rsc/HandEra.r b/handera-sdk-105/examples/Mail/Rsc/HandEra.r new file mode 100644 index 0000000..bf63623 --- /dev/null +++ b/handera-sdk-105/examples/Mail/Rsc/HandEra.r @@ -0,0 +1,29 @@ +/*********************************************************************** + * + * Copyright (c) 1999-2001, TRG, All Rights Reserved + * + * PROJECT: HandEra 330 + * + * FILE: HandEra.r + * + * DESCRIPTION: + * + * AUTHOR: John Ehm + * + * DATE: 01/17/01 + * + **********************************************************************/ + + +type 'sKst' { + //Currently no data is stored in resource, need dummy otherwise + //resource is not linked in + unsigned longint; +}; + + +resource 'sKst' (1000, "HandEra Aware") +{ + 0x00000001; + +}; diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailMessage.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailNewMsg.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailOptions.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailPreferences.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailReply.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailSync.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/MailTruncate.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailDetails.rsrc new file mode 100644 index 0000000..6f920f7 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailDetails.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailEdit.rsrc new file mode 100644 index 0000000..5d92afe Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailEdit.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailList.rsrc new file mode 100644 index 0000000..4488680 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailList.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailMessage.rsrc new file mode 100644 index 0000000..ac298b3 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailMessage.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailMisc.rsrc new file mode 100644 index 0000000..586e3b9 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailMisc.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailNewMsg.rsrc new file mode 100644 index 0000000..e5e00ce Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailNewMsg.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailOptions.rsrc new file mode 100644 index 0000000..d1aff63 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailOptions.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailPreferences.rsrc new file mode 100644 index 0000000..bee2a52 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailPreferences.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailReply.rsrc new file mode 100644 index 0000000..a677811 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailReply.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailSync.rsrc new file mode 100644 index 0000000..1a46203 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailSync.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailTruncate.rsrc new file mode 100644 index 0000000..f822f18 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/deDE/Resource.Frk/MailTruncate.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailMessage.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailNewMsg.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailOptions.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailPreferences.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailReply.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailSync.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/MailTruncate.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailDetails.rsrc new file mode 100644 index 0000000..d2d45ef Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailDetails.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailEdit.rsrc new file mode 100644 index 0000000..f530cbc Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailEdit.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailList.rsrc new file mode 100644 index 0000000..3f51f81 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailList.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailMessage.rsrc new file mode 100644 index 0000000..719c1ac Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailMessage.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailMisc.rsrc new file mode 100644 index 0000000..c6ec5d0 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailMisc.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailNewMsg.rsrc new file mode 100644 index 0000000..ce857d5 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailNewMsg.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailOptions.rsrc new file mode 100644 index 0000000..dcba1e2 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailOptions.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailPreferences.rsrc new file mode 100644 index 0000000..5a9b787 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailPreferences.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailReply.rsrc new file mode 100644 index 0000000..257b3c5 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailReply.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailSync.rsrc new file mode 100644 index 0000000..75be37e Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailSync.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailTruncate.rsrc new file mode 100644 index 0000000..1d91b76 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/esES/Resource.Frk/MailTruncate.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailMessage.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailNewMsg.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailOptions.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailPreferences.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailReply.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailSync.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/MailTruncate.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailDetails.rsrc new file mode 100644 index 0000000..fd20bf1 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailDetails.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailEdit.rsrc new file mode 100644 index 0000000..8947442 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailEdit.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailList.rsrc new file mode 100644 index 0000000..14cdf19 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailList.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailMessage.rsrc new file mode 100644 index 0000000..f20ca2b Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailMessage.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailMisc.rsrc new file mode 100644 index 0000000..619ea78 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailMisc.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailNewMsg.rsrc new file mode 100644 index 0000000..57322e5 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailNewMsg.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailOptions.rsrc new file mode 100644 index 0000000..16cf347 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailOptions.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailPreferences.rsrc new file mode 100644 index 0000000..e2b69ec Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailPreferences.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailReply.rsrc new file mode 100644 index 0000000..d7609e5 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailReply.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailSync.rsrc new file mode 100644 index 0000000..b1a91f0 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailSync.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailTruncate.rsrc new file mode 100644 index 0000000..a5b4b14 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/frFR/Resource.Frk/MailTruncate.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailMessage.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailNewMsg.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailOptions.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailPreferences.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailReply.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailSync.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/MailTruncate.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailDetails.rsrc new file mode 100644 index 0000000..92366c4 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailDetails.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailEdit.rsrc new file mode 100644 index 0000000..885ed98 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailEdit.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailList.rsrc new file mode 100644 index 0000000..a5a0572 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailList.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailMessage.rsrc new file mode 100644 index 0000000..d071f8f Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailMessage.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailMisc.rsrc new file mode 100644 index 0000000..d875013 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailMisc.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailNewMsg.rsrc new file mode 100644 index 0000000..1fc83e1 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailNewMsg.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailOptions.rsrc new file mode 100644 index 0000000..48657f3 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailOptions.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailPreferences.rsrc new file mode 100644 index 0000000..e542b4c Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailPreferences.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailReply.rsrc new file mode 100644 index 0000000..d3ae364 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailReply.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailSync.rsrc new file mode 100644 index 0000000..57fe708 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailSync.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailTruncate.rsrc new file mode 100644 index 0000000..4cbc920 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/itIT/Resource.Frk/MailTruncate.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailMessage.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailNewMsg.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailOptions.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailPreferences.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailReply.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailSync.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/MailTruncate.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailDetails.rsrc new file mode 100644 index 0000000..af1babc Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailDetails.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailEdit.rsrc new file mode 100644 index 0000000..28e206f Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailEdit.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailList.rsrc new file mode 100644 index 0000000..da4023a Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailList.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailMessage.rsrc new file mode 100644 index 0000000..8158144 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailMessage.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailMisc.rsrc new file mode 100644 index 0000000..1bedba7 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailMisc.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailNewMsg.rsrc new file mode 100644 index 0000000..dd5a9d1 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailNewMsg.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailOptions.rsrc new file mode 100644 index 0000000..875937e Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailOptions.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailPreferences.rsrc new file mode 100644 index 0000000..bd551df Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailPreferences.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailReply.rsrc new file mode 100644 index 0000000..a6a5209 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailReply.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailSync.rsrc new file mode 100644 index 0000000..e9874c4 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailSync.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailTruncate.rsrc new file mode 100644 index 0000000..3acc8af Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Localized/jpJP/Resource.Frk/MailTruncate.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailDetails.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailEdit.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailList.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailMessage.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailMisc.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailNewMsg.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailOptions.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailPreferences.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailReply.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailSync.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/MailTruncate.rsrc new file mode 100644 index 0000000..e69de29 diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailDetails.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailDetails.rsrc new file mode 100644 index 0000000..9528907 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailDetails.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailEdit.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailEdit.rsrc new file mode 100644 index 0000000..0d37764 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailEdit.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailList.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailList.rsrc new file mode 100644 index 0000000..1a342c1 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailList.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailMessage.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailMessage.rsrc new file mode 100644 index 0000000..0c7f7a3 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailMessage.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailMisc.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailMisc.rsrc new file mode 100644 index 0000000..995486d Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailMisc.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailNewMsg.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailNewMsg.rsrc new file mode 100644 index 0000000..f5db24f Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailNewMsg.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailOptions.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailOptions.rsrc new file mode 100644 index 0000000..4176539 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailOptions.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailPreferences.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailPreferences.rsrc new file mode 100644 index 0000000..a84e812 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailPreferences.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailReply.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailReply.rsrc new file mode 100644 index 0000000..7688690 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailReply.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailSync.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailSync.rsrc new file mode 100644 index 0000000..9b454b8 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailSync.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailTruncate.rsrc b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailTruncate.rsrc new file mode 100644 index 0000000..7d53920 Binary files /dev/null and b/handera-sdk-105/examples/Mail/Rsc/Resource.Frk/MailTruncate.rsrc differ diff --git a/handera-sdk-105/examples/Mail/Src/Mail.c b/handera-sdk-105/examples/Mail/Src/Mail.c new file mode 100644 index 0000000..fbfe818 --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/Mail.c @@ -0,0 +1,9635 @@ +/****************************************************************************** + * + * Copyright (c) 1996-2000 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: Mail.c + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This is the Mail application's main module. + * + * History: + * May 30, 1996 Created by Art Lamb + * Feb 2, 2001 Added localeChanged notification support + * + *****************************************************************************/ + +#include + +#include + +#include "Mail.h" + +/* HandEra */ +#include "vga.h" +/* end HandEra */ + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ + +// Define the minimum OS version we support +#define ourMinVersion sysMakeROMVersion(4,0,0,sysROMStageDevelopment,0) + +#define noRecordSelected -1 +#define noNewRecord -1 +#define noDate 0 + +// Categories +#define inboxCategory 0 +#define outboxCategory 1 +#define deletedCategory 2 +#define filedCategory 3 +#define draftCategory 4 +//mgmg +#define ignoreCategory 13 +// this category is used to store a "Revert" record. AS needed. +// It will be marked as deleted, and stored at the end. So if the user Sync's it +// will properly dissapear. + + +// Column widths in List View +/* HandEra */ +#define listDateWidth (vgaExists ? (VgaIsVgaFont(ListFont) ? 38 : 25) : 25) +#define listScrollBarWidth (vgaExists ? 11 : 9) +#define listColumnSpacing (vgaExists ? 6 : 4) +#define listIconWidth (vgaExists ? 23 : 15) +//#define listDateWidth 25 +//#define listScrollBarWidth 9 +//#define listColumnSpacing 4 +//#define listIconWidth 15 +/* end HandEra */ + +// Options dialog sort order list items. +#define sortByDateItem 0 +#define sortByFromItem 1 +#define sortBySubjectItem 2 + + +// Update codes, used to determine how the to do list should +// be redrawn. +#define updateDisplayOptsChanged 0x01 +#define updatePurge 0x02 +#define updateFontChanged 0x04 +#define updateSelectCurrentRecord 0x80 + + +// Maximum length and width of the Mesage View's title. +#define maxMessageTitleLen 40 +#define maxMessageTitleLenWidth 130 + +// Maximum length and width of the Edit View's title. +#define maxEditTitleLen 40 +#define maxEditTitleLenWidth 110 + + +// Edit view table's rows and columns +#define newToRow 0 +#define newCCRow 1 +#define newBCCRow 2 +#define newSubjectRow 3 +#define newBodyRow 4 + +#define maxNewRows 5 + +#define newLabelColumn 0 +#define newTextColumn 1 + +//mgmg add some space after the label +#define spaceAfterLabel 3 + +// Max lines per field in new view +#define maxNewAddressLines 2 +#define maxNewSubjectLines 2 + +//mgmg +//#define maxNewFieldChars 4000 +#define maxNewFieldChars 10000 + +// Update codes +#define updateRestoreFocus 1 +#define updateReinitialize 2 + +// Space between columns in find results dialog. +#define findColumnSpacing 4 + +// Max name length for addresses in the find results dialog. +#define maxFindFromNameLen 40 + +// Maximum width of a commented message (message where each line starts +// with a >). +#define commentedMsgWidth 119 + +// Length the buffer used to format a reply message. +#define replayBufferLen 200 + + +// Maximin input length for new message fields +#define maxAddressLength 4096 +#define maxSubjectLength 256 +#define maxBodyLength 4096 +#define maxFilterLength 256 + +//distance from the title to draw the Message x of y text in the message view +#define kMessageTitleOffset 9 + +/*********************************************************************** + * + * Internal Structutes + * + ***********************************************************************/ + +// This is the structure of the data stored in the state file. +typedef struct { + FontID messageFont; + FontID listFont; + FontID editFont; + Boolean showDates; + Boolean includeOriginalText; + Boolean commentOriginalText; + Boolean confirmDelete; + Boolean showFullHeader; + Boolean attachSignature; + Boolean confirmRead; + Boolean confirmDelivery; + UInt8 reserved; + UInt16 revertCategory; +} MailPreferenceType; + +#define kDefaultListFont stdFont +#define kDefaultMessageFont stdFont +#define kDefaultEditFont stdFont + +typedef struct { + VgaRotateModeType rotation; + Boolean rememberRotation; +} MailRotationPrefType; + + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + + DmOpenRef MailDB; // Mail database + + TimeFormatType TimeFormat; // system preference + DateFormatType DateFormat; + +static char CategoryName [dmCategoryLength]; // name of the current categorg + +// The following global variables are used to keep track of the edit +// state of the application. + UInt16 CurrentRecord = -1; // record being edited +static UInt16 NewRecord = -1; // index of unsend new message +static UInt16 TopVisibleRecord = 0; // top visible record in list view +static UInt16 CurrentCategory = 0; // currently displayed category +static Int16 MessagesInCategory; // number of messages in the current category +static UInt16 UnreadMessages = 0; // number of unread messages + +static UInt16 NewViewCurrentRowID = 0; +static Boolean NewViewShowBCC = false; +static UInt16 NewScrollPosition [maxNewRows]; // Scroll position of each field in the New View. + +static Boolean ItemSelected = false; // true if a list view item is selected +static UInt16 EditPosition = 0; // position of the insertion point in the current field +static UInt16 EditBodyPosition = 0; // position of the insertion point in the body field +static UInt16 EditSelectionLength = 0; // length of the current selection. + EditFieldType EditViewField; // field to edit in the Edit view + Boolean EditViewEditRecord; // true if editing a record, false if editing hotsync options +static Boolean RestoreFromEditView = false; // true if we a re returning from the edit view +static Boolean StashedNewViewShowBCC = false; + +// Global variable used by Message View + MsgFieldType MessageTopField; // top visible field + UInt16 MessageScrollPos; // position of first visible character in top visible field + MsgSelectFieldType MessageSelectStartField; + MsgSelectFieldType MessageSelectEndField; + UInt16 MessageSelectStartPos; + UInt16 MessageSelectEndPos; + +//mgmg + MemHandle MessageOriginalRecordData = NULL; + UInt16 MessageRevertCategory = 0; + +// globals for the New view +// * mgolden 10/6/97 changed for the rocky fonts + UInt16 gNewViewTableHeight; // the original height of the table object, used to calculate the + // correct new height based on the font. + +// The following global variables are saved to a state file. + FontID MessageFont = kDefaultListFont; // font used in message view + FontID ListFont = kDefaultMessageFont; // font used in message view + FontID EditFont = kDefaultEditFont; // font used in message view + +static Boolean ShowDates = true; // true if dates are displayed in the list view +static Boolean IncludeOriginalText = true; // true to include original message in reply +static Boolean CommentOriginalText = false; // true to comment original message in reply +static Boolean ConfirmDelete = true; // true if we display an alert before deleting a message + +static MemHandle MessageTitleH; // Title of message view. + Boolean ShowFullHeader = false; // True to display full header in message view +static Boolean AttachSignature = false; // True to always attach signature +static Boolean ConfirmRead = false; // True to always confirm that a message was read +static Boolean ConfirmDelivery = false; // True to always confirm that a message was delivered + +static MemHandle EditTitleH; // Title of edit view. + + UInt16 TruncateLen; // Maximun length of retrieved message + MemHandle SyncUIStateH = 0; // Save save of the HotSync dialog + + +static UInt16 ReturnToView = ListView; // View to return to when a message is sent +static UInt32 *crIDs = NULL; // The creator IDs for default +static Char *appNames = NULL; // App names for default +static Char **appNamesArray = NULL; +static UInt32 appCnt = 0; // Num of possible defaults + +/* HandEra */ +static VgaScreenStateType gScreenState; +Boolean vgaExists = false; +/* end HandEra */ +/*********************************************************************** + * + * Internal Routines + * + ***********************************************************************/ + +static UInt16 NewViewGetFieldHeight (UInt16 recordNum, Int16 rowID, UInt16 width); +static void NewViewInitRow (TablePtr table, Int16 row, Int16 rowID, UInt16 height); +static void DrawString (Char * str, Int16 x, Int16 y, Int16 width); +static void MessageViewDrawMessage (void); +static void MessageViewToggleFont (void); +static void EditViewToggleFont (void); +static UInt16 NewViewGetLineCount (UInt16 recordNum, Int16 rowID, UInt16 width); +static Boolean MessageUndelete(void); +static void MessageViewMarkUnRead (void); +static void MessageViewEnableButtons(FormPtr frm); +static void ListViewSelectRecord (FormPtr frm, UInt16 recordNum, Boolean scrollToSelect); +static void Search (FindParamsPtr findParams); +static Err MessageViewRevert(DmOpenRef dbP, UInt16 * index); +static void MessageViewInitializRevert(void); +static void MessageViewCleanUpRevert(void); +static void SaveRevert(void); +static void RestoreRevert(Boolean keepIt); +static void ListViewLoadTable (FormPtr frm, UInt16 recordNum); +static void ListViewLoadRecords (FormPtr frm); +#ifdef DO_ROM_CHECK +static Err RomVersionCompatible (UInt32 requiredVersion, UInt16 launchFlags); +#endif +static FontID SelectFont (FontID currFontID); +static UInt16 ListViewNumberOfRows (TablePtr table); +static void NewViewToggleFont (void); +static UInt16 NewViewNumberOfRows (TablePtr table); +static void NewViewLoadTable(FormPtr frm); + +static void MailLoadPrefs(void); // BGT +static void MailSavePrefs(void); // BGT +static Err ParseMailtoURL(MailAddRecordParamsPtr newMsgP, MemPtr cmdPBP, + Char *buf); +static Boolean PrvGetNameValuePair(Char **strP, Int16 * strLen, Char **nameP, + Int16 * nameLen, Char **valueP, + Int16 * valueLen); +static void PrvSetMailAppsList(Int32 listSelection); +static void RegisterLocaleChangedNotification(void); +static Err CreateDefaultDatabase(void); +static void EventLoop (void); + +#ifdef DO_ROM_CHECK +/*********************************************************************** + * + * FUNCTION: RomVersionCompatible + * + * DESCRIPTION: Check that the ROM version meets the + * minimum requirement. Warn if the app was switched to. + * + * PARAMETERS: requiredVersion - minimum rom version required + * (see sysFtrNumROMVersion in SystemMgr.h + * for format) + * launchFlags - flags indicating how the application was + * launched. A warning is displayed only if + * these flags indicate that the app is + * launched normally. + * + * RETURNED: zero if rom is compatible else an error code + * + ***********************************************************************/ +static Err RomVersionCompatible (UInt32 requiredVersion, UInt16 launchFlags) +{ + UInt32 romVersion; + + + // See if we're on in minimum required version of the ROM or later. + // The system records the version number in a feature. A feature is a + // piece of information which can be looked winUp by a creator and feature + // number. + FtrGet(sysFtrCreator, sysFtrNumROMVersion, &romVersion); + if (romVersion < requiredVersion) + { + // If the user launched the app from the launcher, explain + // why the app shouldn't run. If the app was contacted for something + // else, like it was asked to find a string by the system find, then + // don't bother the user with a warning dialog. These flags tell how + // the app was launched to decided if a warning should be displayed. + if ((launchFlags & (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) == + (sysAppLaunchFlagNewGlobals | sysAppLaunchFlagUIApp)) + { + FrmAlert (RomIncompatibleAlert); + + // Pilot 1.0 will continuously relaunch this app unless we switch to + // another safe one. The sysFileCDefaultApp is considered "safe". + if (romVersion < 0x02000000) + { + Err err; + + AppLaunchWithCommand(sysFileCDefaultApp, sysAppLaunchCmdNormalLaunch, NULL); + } + } + + return (sysErrRomIncompatible); + } + + return 0; +} +#endif + +/*********************************************************************** + * + * FUNCTION: SetDBBackupBit + * + * DESCRIPTION: This routine sets the backup bit on the given database. + * This is to aid syncs with non Palm software. + * If no DB is given, open the app's default database and set + * the backup bit on it. + * + * PARAMETERS: dbP - the database to set backup bit, + * can be NULL to indicate app's default database + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * grant 4/1/99 Initial Revision + * + ***********************************************************************/ +void SetDBBackupBit(DmOpenRef dbP) +{ + DmOpenRef localDBP; + LocalID dbID; + UInt16 cardNo; + UInt16 attributes; + + // Open database if necessary. If it doesn't exist, simply exit (don't create it). + if (dbP == NULL) + { + localDBP = DmOpenDatabaseByTypeCreator (mailDBType, sysFileCMail, dmModeReadWrite); + if (localDBP == NULL) return; + } + else + { + localDBP = dbP; + } + + // now set the backup bit on localDBP + DmOpenDatabaseInfo(localDBP, &dbID, NULL, NULL, &cardNo, NULL); + DmDatabaseInfo(cardNo, dbID, NULL, &attributes, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); + attributes |= dmHdrAttrBackup; + DmSetDatabaseInfo(cardNo, dbID, NULL, &attributes, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); + + // close database if necessary + if (dbP == NULL) + { + DmCloseDatabase(localDBP); + } +} + + +/*********************************************************************** + * + * FUNCTION: StartApplication + * + * DESCRIPTION: This routine opens the application's database, laods the + * saved-state information and initializes global variables. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/30/96 Initial Revision + * MGolden 7/14/97 Added a call to RestoreRevert() + * MGolden 8/11/97 Fixed the Missing app info block bug (code from Roger.) + * grant 4/7/99 Set the backup bit when creating the DB. + * jmp 10/18/99 Replaced inline code with call to MailGetDatabase(). + * CS 11/14/00 Use PrefGetPreference instead of PrefGetPreferences. + * + ***********************************************************************/ +static UInt16 StartApplication (void) +{ + Err err = errNone; + UInt16 index; + UInt32 uniqueID; + Boolean synchronize = false; + MailPackedDBRecordPtr recordP; + UInt32 vgaVersion; + + // Get the date format from the system preferences. + DateFormat = (DateFormatType)PrefGetPreference(prefDateFormat); + TimeFormat = (TimeFormatType)PrefGetPreference(prefTimeFormat); + + // Find the application's data file. If it doesn't exist create it. + err = MailGetDatabase (&MailDB, dmModeReadWrite); + if (err) + return err; + + /* HandEra */ + if (_TRGVGAFeaturePresent(&vgaVersion)) + { + VgaRotateModeType rotate; + + vgaExists = true; + + VgaGetScreenMode(NULL, &rotate); + VgaSetScreenMode(screenMode1To1, rotate); + } + else + vgaExists = false; + /* end HandEra */ + + // Read the preferences / saved-state information. + MailLoadPrefs(); + + // Get the MemHandle of an unsent message for the last time the application + // ran. + NewRecord = noNewRecord; + uniqueID = MailGetUnsentMessage (MailDB); + + //do the restore here...since the database may move around before it returns + RestoreRevert(uniqueID); + + //now find the unique id record to edit. + if (uniqueID) + { + DmFindRecordByID (MailDB, uniqueID, &NewRecord); + if (DmQueryRecord (MailDB, NewRecord) == 0) + NewRecord = noNewRecord; + } + + + // Get the count of the unread messages. + index = 0; + while (true) + { + DmSeekRecordInCategory (MailDB, &index, 0, dmSeekForward, inboxCategory); + if (DmGetLastErr()) break; + + recordP = MemHandleLock (DmQueryRecord (MailDB, index)); + if (! recordP->flags.read) + UnreadMessages++; + MemPtrUnlock (recordP); + index++; + } + + + TopVisibleRecord = 0; + CurrentRecord = noRecordSelected; + + //RestoreRevert(NewRecord); + + MessagesInCategory = DmNumRecordsInCategory (MailDB, CurrentCategory); + + return (err); +} + + +/*********************************************************************** + * + * FUNCTION: StopApplication + * + * DESCRIPTION: This routine closes the application's database + * and saves the current state of the application. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/30/96 Initial Revision + * MGolden 7/14/97 Added a call to SaveRevert() + * + ***********************************************************************/ +static void StopApplication (void) +{ + // Write the preferences / saved-state information. + MailSavePrefs(); // (BGT) + + // Send a frmSave event to all the open forms. + FrmSaveAllForms (); + + // Close all the open forms. + FrmCloseAllForms (); + + //save revert info + SaveRevert(); + + // Free all of the list selection stuff for default app + if(appNamesArray) + MemPtrFree(appNamesArray); + if(appNames) + MemPtrFree(appNames); + if(crIDs) + MemPtrFree(crIDs); + + // Bug fix since SyncUIStateH was never freed when exiting the application + // in the EditView coming from the Sync Dialog + // There should be a better way but it should work for now + if (SyncUIStateH) + { + MemHandleFree(SyncUIStateH); + } + + // Close the application's data file. + DmCloseDatabase (MailDB); +} + + +/*********************************************************************** + * + * FUNCTION: SyncNotification + * + * DESCRIPTION: This routine is a entry point of the to do application. + * It is called when the to do application's database is + * synchronized. This routine will resort the database and + * reset the state file info if necessary. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/30/96 Initial Revision + * jmp 10/18/99 Use MailGetDatabase() instead of DmOpenDatabaseByTypeCreator(). + * + ***********************************************************************/ +static void SyncNotification (void) +{ + Err err = errNone; + DmOpenRef dbP; + + // Open the application's data file. + err = MailGetDatabase (&dbP, dmModeReadWrite); + if (err) return; + + // Resort the database. + MailSort (dbP); + + DmCloseDatabase (dbP); +} + + + +/*********************************************************************** + * + * FUNCTION: CreateDefaultDatabase + * + * DESCRIPTION: This routine creates the default database from the + * saved image in a resource in the application. + * + * PARAMETERS: none + * + * RETURNED: 0 - if no error + * otherwise appropriate error value + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * vivek 02/01/01 Initial Revision + * + ***********************************************************************/ +static Err CreateDefaultDatabase(void) +{ + MemHandle resH; + DmOpenRef dbP; + Err error = errNone; + + // Attempt to get our default data image and create our + // database. + resH = DmGet1Resource(sysResTDefaultDB, sysResIDDefaultDB); + if (resH) + { + error = DmCreateDatabaseFromImage(MemHandleLock(resH)); + + if (!error) + { + MemHandleUnlock(resH); + DmReleaseResource(resH); + + // Set the bakcup bit on the newly created DB. + SetDBBackupBit(NULL); + } + } + + // If there is no default data, or we had a problem creating it, + // then attempt to create an empty database. + if (!resH || error) + { + error = MailGetDatabase (&dbP, dmModeReadWrite); + + if (!error) + DmCloseDatabase(dbP); + + } + return error; + +} + + +/*********************************************************************** + * + * FUNCTION: RegisterLocaleChangedNotification + + * + * DESCRIPTION: Register with NotifyMgr for localeChanged notifications. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * vivek 02/01/01 Initial Revision + * + ***********************************************************************/ +static void RegisterLocaleChangedNotification(void) +{ + UInt16 cardNo; + LocalID dbID; + Err err; + + err = SysCurAppDatabase(&cardNo, &dbID); + ErrNonFatalDisplayIf(err != errNone, "can't get app db info"); + if(err == errNone) + { + err = SysNotifyRegister(cardNo, dbID, sysNotifyLocaleChangedEvent, + NULL, sysNotifyNormalPriority, NULL); + +#if EMULATION_LEVEL == EMULATION_NONE + ErrNonFatalDisplayIf((err != errNone) && (err != sysNotifyErrDuplicateEntry), "can't register"); +#endif + + } + + return; +} + + + + + +/*********************************************************************** + * + * FUNCTION: GoToItem + * + * DESCRIPTION: This routine is called when the "Go to" button + * in the text search dialog is pressed. + * + * PARAMETERS: goToParams - where to go to + * launchingApp - true is the application is being launched + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 06/27/96 Initial Revision + * kwk 12/03/98 Fixed param order in call to MemSet. + * + ***********************************************************************/ +static void GoToItem (GoToParamsPtr goToParams, Boolean launchingApp) +{ + UInt16 attr; + UInt16 category; + UInt16 recordNum; + UInt32 uniqueID; + EventType event; + + recordNum = goToParams->recordNum; + + + // If the application is already running, close all the open forms. If + // the current record is blank, then it will be deleted, so we'll get + // the unique id of the record and use it to find the record index + // after all the forms are closed. + if (! launchingApp) + { + DmRecordInfo (MailDB, recordNum, NULL, &uniqueID, NULL); + + FrmSaveAllForms (); + FrmCloseAllForms (); + + DmFindRecordByID (MailDB, uniqueID, &recordNum); + } + + // Make the record visible in the List View. + TopVisibleRecord = recordNum; + + + // Change the current category. + DmRecordInfo (MailDB, recordNum, &attr, NULL, NULL); + category = (attr & dmRecAttrCategoryMask); + if (CurrentCategory != category) + { + CurrentCategory = category; + MessagesInCategory = DmNumRecordsInCategory (MailDB, CurrentCategory); + } + + + // Change the "show full header" setting such that the found string + // will be displayable. + switch (goToParams->matchFieldNum) + { + case msgFieldSentTo: + ShowFullHeader = false; + break; + + case msgFieldTo: + case msgFieldFrom: + case msgFieldSubject: + case msgFieldCC: + ShowFullHeader = true; + break; + } + + // Send an event to goto a form and select the matching text. + MemSet (&event, sizeof(EventType), 0); + + event.eType = frmLoadEvent; + event.data.frmLoad.formID = MessageView; + EvtAddEventToQueue (&event); + + event.eType = frmGotoEvent; + event.data.frmGoto.formID = MessageView; + event.data.frmGoto.recordNum = recordNum; + event.data.frmGoto.matchPos = goToParams->matchPos; + event.data.frmGoto.matchLen = goToParams->matchCustom; + event.data.frmGoto.matchFieldNum = goToParams->matchFieldNum; + EvtAddEventToQueue (&event); +} + + +/*********************************************************************** + * + * FUNCTION: AddMessage + * + * DESCRIPTION: This routine add a mail new message to the mail datebase + * it is called via a launch command by other applications. + * + * PARAMETERS: msgParams - parameter block containing the new message. + * outBox - put in outBox if true, otherwise drafts + * + * RETURNED: error code + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 1/21/97 Initial Revision + * MGolden 7/9/97 Fixed bug where database was not open. + * jmp 10/18/99 Replace inline code with call to MailGetDatabase(). + * grant 11/30/99 Re-fixed bug where database was not open. + * + ***********************************************************************/ +static Err AddMessage (MailAddRecordParamsPtr msgParams, Boolean outBox) +{ + Err err; + UInt16 attr; + UInt16 index; + DmOpenRef dbP; + MailDBRecordType record; + + if (! msgParams->to) + return (0); + + MemSet (&record, sizeof (MailDBRecordType), 0); + + record.flags.signature = msgParams->signature; + record.flags.confirmRead = msgParams->confirmRead; + record.flags.confirmDelivery = msgParams->confirmDelivery; + record.flags.priority = msgParams->priority; + + if (msgParams->subject) + record.subject = msgParams->subject; + +//removed this because the from field is ignored for outgoing e-mail +// if (msgParams->from) +// record.from = msgParams->from; + + if (msgParams->to) + record.to = msgParams->to; + + if (msgParams->cc) + record.cc = msgParams->cc; + + if (msgParams->bcc) + record.bcc = msgParams->bcc; + + if (msgParams->replyTo) + record.replyTo = msgParams->replyTo; + + if (msgParams->body) + record.body = msgParams->body; + + // Find the application's data file; if it doesn't exist, create it. + err = MailGetDatabase (&dbP, dmModeReadWrite); + if (err) return err; + + // Insert the new record. + err = MailNewRecord (dbP, &record, &index); + if (err) goto exit; + + // Put the new record in the outbox category. + DmRecordInfo (dbP, index, &attr, NULL, NULL); + attr &= ~dmRecAttrCategoryMask; + if(outBox) + attr |= outboxCategory | dmRecAttrDirty; + else + attr |= draftCategory | dmRecAttrDirty; + if (msgParams->secret) + attr |= dmRecAttrSecret; + DmSetRecordInfo (dbP, index, &attr, NULL); + + +exit: + DmCloseDatabase (dbP); + + return (err); +} + + + +/*********************************************************************** + * + * FUNCTION: SeekRecord + * + * DESCRIPTION: Given the index of a to do record, this routine scans + * forewards or backwards for displayable 'to do' records. + * + * PARAMETERS: indexP - pointer to the index of a record to start from; + * the index of the record sought is returned in + * this parameter. + * + * offset - number of records to skip: + * 0 - mean seek from the current record to the + * next display record, if the current record is + * a displayable record, its index is retuned. + * 1 - mean seek foreward, skipping one displayable + * record + * -1 - menas seek backwards, skipping one + * displayable record + * + * + * RETURNED: false is return if a displayable record was not found. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/3/96 Initial Revision + * + ***********************************************************************/ +static Boolean SeekRecord (UInt16 * indexP, Int16 offset, Int16 direction) +{ + DmSeekRecordInCategory (MailDB, indexP, offset, direction, CurrentCategory); + if (DmGetLastErr()) return (false); + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: CreateRecord + * + * DESCRIPTION: This routine creates a new message record. + * + * PARAMETERS: nothing + * + * RETURNED: true if the record was sucessfully created. + * + * NOTE: This routine may change the index of the CurrentRecord, + * the global variable the holds this index is changed by + * this routine. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/6/96 Initial Revision + * + ***********************************************************************/ +static Boolean CreateRecord (void) +{ + Err err; + UInt16 attr; + UInt32 uniqueID; + MailDBRecordType record; + + if (CurrentRecord != noRecordSelected) + DmRecordInfo (MailDB, CurrentRecord, NULL, &uniqueID, NULL); + + + MemSet (&record, sizeof (MailDBRecordType), 0); + record.flags.priority = priorityNormal; + record.flags.signature = AttachSignature; + record.flags.confirmRead = ConfirmRead; + record.flags.confirmDelivery = ConfirmDelivery; + + // Add a new record into the database. + err = MailNewRecord (MailDB, &record, &NewRecord); + + // If the allocate failed, display a warning. + if (err) + { + FrmAlert (DeviceFullAlert); + NewRecord = noNewRecord; + return (false); + } + + // Put the new record in the draft category. + DmRecordInfo (MailDB, NewRecord, &attr, NULL, NULL); + attr &= ~(dmRecAttrCategoryMask | dmRecAttrDirty); + attr |= draftCategory; + DmSetRecordInfo (MailDB, NewRecord, &attr, NULL); + + if (CurrentCategory == draftCategory) + MessagesInCategory++; + + if (CurrentRecord != noRecordSelected) + DmFindRecordByID (MailDB, uniqueID, &CurrentRecord); + + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: DirtyRecord + * + * DESCRIPTION: Mark a record dirty (modified). Record marked dirty + * will be synchronized. + * + * PARAMETERS: record index + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/30/96 Initial Revision + * + ***********************************************************************/ +static void DirtyRecord (UInt16 index) +{ + UInt16 attr; + + DmRecordInfo (MailDB, index, &attr, NULL, NULL); + attr |= dmRecAttrDirty; + DmSetRecordInfo (MailDB, index, &attr, NULL); +} + + +/*********************************************************************** + * + * FUNCTION: PurgeDeletedRecord + * + * DESCRIPTION: This routine deletes all the mail messages in the + * "deleted" category. + * + * PARAMETERS: nothing + * + * RETURNED: true if record were purged + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/12/96 Initial Revision + * + ***********************************************************************/ +static Boolean PurgeDeletedRecord (void) +{ + UInt16 attr; + UInt16 index; + UInt16 numRecords; + UInt32 uniqueID; + UInt32 newUniqueID; + + + // Check if there are any records to delete. + index = 0; + DmSeekRecordInCategory (MailDB, &index, 0, dmSeekForward, deletedCategory); + if (DmGetLastErr()) + { + FrmAlert(NothingToPurgeAlert); + return (false); + } + + if (FrmAlert(PurgeAlert) != PurgeYes) + return (false); + + + if (CurrentRecord != noRecordSelected) + { + DmRecordInfo (MailDB, CurrentRecord, &attr, &uniqueID, NULL); + if ((attr & dmRecAttrCategoryMask) == deletedCategory) + CurrentRecord = noRecordSelected; + } + + + if (NewRecord != noRecordSelected) + DmRecordInfo (MailDB, NewRecord, &attr, &newUniqueID, NULL); + + + + numRecords = DmNumRecords (MailDB); + + index = numRecords; + while (true) + { + DmSeekRecordInCategory (MailDB, &index, 0, dmSeekBackward, + deletedCategory); + if (DmGetLastErr()) break; + + DmDeleteRecord (MailDB, index); + + // Move deleted record to the end of the index so that the + // sorting routine will work. + DmMoveRecord (MailDB, index, numRecords); + } + + + if (CurrentRecord != noRecordSelected) + DmFindRecordByID (MailDB, uniqueID, &CurrentRecord); + + + if (NewRecord != noRecordSelected) + DmFindRecordByID (MailDB, newUniqueID, &NewRecord); + + + MessagesInCategory = DmNumRecordsInCategory (MailDB, CurrentCategory); + + // If we're in the deleted category, set the following global the controls + // which view we return to, so that we will return to the List View. + if (CurrentCategory == deletedCategory) + ReturnToView = ListView; + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: SendMessage + * + * DESCRIPTION: This routine send a new mail message. + * + * PARAMETERS: nothing + * + * RETURNED: true if the record was sucessfully send. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/6/96 Initial Revision + * + ***********************************************************************/ +static Boolean SendMessage (void) +{ + Err err; + UInt16 attr; + UInt32 uniqueID; + Boolean noAddress; + MemHandle recordH; + MailDBRecordType record; + + + // Varify that we have a "to" address. + MailGetRecord (MailDB, NewRecord, &record, &recordH); + noAddress = (*record.to == 0); + MemHandleUnlock (recordH); + + if (noAddress) + { + FrmAlert (NoAddressAlert); + return (false); + } + + // Get the unique id of the current record, it may move. + if (CurrentRecord != noRecordSelected) + DmRecordInfo (MailDB, CurrentRecord, NULL, &uniqueID, NULL); + + + // Move the record to its corrent sort position. + err = MailSortRecord (MailDB, &NewRecord); + if (err) + { + FrmAlert (DeviceFullAlert); + return (false); + } + + + // Put the new record in the outbox category. + DmRecordInfo (MailDB, NewRecord, &attr, NULL, NULL); + attr &= ~dmRecAttrCategoryMask; + attr |= outboxCategory | dmRecAttrDirty; + DmSetRecordInfo (MailDB, NewRecord, &attr, NULL); + + + // Clear the datebase value that keep track of the unsent message. + NewRecord = noNewRecord; + MailSetUnsentMessage (MailDB, 0); + + if (CurrentCategory == outboxCategory) + MessagesInCategory++; + else if (CurrentCategory == draftCategory) + MessagesInCategory--; + + + // Find the current record. + if (CurrentRecord != noRecordSelected) + DmFindRecordByID (MailDB, uniqueID, &CurrentRecord); + + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: SaveDraftMessage + * + * DESCRIPTION: This routine stores an new mail message in the draft + * catagory + * + * PARAMETERS: quite - if false an alert is displayed to confirm + * the operation + * deleted - returned: true if record was removed from the + * database + * + * RETURNED: true if the record was sucessfully saved. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/18/96 Initial Revision + * MGolden 7/14/97 revert the message if the user says no to the save + * in draft dialog + * MGolden 7/16/97 fixed bug where current record was not correct if the + * User says no to the save in draft dialog from the draft folder. + * MGolden 7/17/97 Changed tohe code so if the user is clearing a message, + * It is not deleted if there is a mesage to revert to. So when + * They are editing a message in the draft folder, and press cancel. + * It's not deleted. + * MGolden 7/28/97 Added the input Param MenuCmd. If true, the user did not select the + * cancel button, but selected the menu command. + ***********************************************************************/ +static Boolean SaveDraftMessage (Boolean quiet, Boolean * deleted, Boolean menuCmd) +{ + Err err; + UInt16 attr; + UInt16 button; + UInt32 uniqueID; + Boolean empty; + Boolean save = false; + MemHandle recordH; + MailDBRecordType record; + Boolean uniqueIdValid = false; + *deleted = false; + + if (NewRecord == noNewRecord) + return (false); + + + // Get the unique id of the current record, it may move. + if (CurrentRecord != noRecordSelected) + { + DmRecordInfo (MailDB, CurrentRecord, NULL, &uniqueID, NULL); + uniqueIdValid = true; + } + + // If the record if empty delete it. + MailGetRecord (MailDB, NewRecord, &record, &recordH); + empty = (! *record.to) && + (! *record.cc) && + (! *record.bcc) && + (! *record.subject) && + (! *record.body); + MemHandleUnlock (recordH); + + + DmRecordInfo (MailDB, NewRecord, &attr, NULL, NULL); + attr &= ~dmRecAttrCategoryMask; + attr |= draftCategory; + + if (empty) + { + if (MessageOriginalRecordData && !menuCmd) + { + //we need to "Revert" this message to the old state + MessageViewRevert(MailDB, &NewRecord); + + //return (true); + } + else + { + if (menuCmd) + { + //show the user an alert! They can not save an empty message + button = FrmAlert (SaveEmptyAlert); + return false; + } + + *deleted = true; + if (attr & dmRecAttrDirty) + { + DmDeleteRecord (MailDB, NewRecord); + DmMoveRecord (MailDB, NewRecord, DmNumRecords (MailDB)); + } + else + DmRemoveRecord (MailDB, NewRecord); + } + } + + else if (quiet) + save = true; + + else + { + button = FrmAlert (SaveDraftAlert); + + if (button == SaveDraftYes) + save = true; + + else if (button == SaveDraftCancel) + return (false); + + else + { + //mgmg + // Was this from the deleted category? If so, leave it there + if (MessageOriginalRecordData) + { + //we need to "Revert" this message to the old state + MessageViewRevert(MailDB, &NewRecord); + + return (true); + } + else + { + *deleted = true; + if (attr & dmRecAttrDirty) + { + DmDeleteRecord (MailDB, NewRecord); + DmMoveRecord (MailDB, NewRecord, DmNumRecords (MailDB)); + } + else + DmRemoveRecord (MailDB, NewRecord); + + //mgmg 7/16 + // clear current record, (we just deleted it) + if (CurrentRecord == NewRecord) + CurrentRecord = noRecordSelected; + } + } + } + + + if (save) + { + // Move the record to its corrent sort position. + err = MailSortRecord (MailDB, &NewRecord); + if (err) + { + if (! quiet) + FrmAlert (DeviceFullAlert); + return (false); + } + + DmSetRecordInfo (MailDB, NewRecord, &attr, NULL); + + //mgmg 7/16 + // assign this record as the current record, if we are in + // the draft folder, it will be selected in the list. + if (CurrentCategory == draftCategory) + CurrentRecord = NewRecord; + } + + + // Clear the datebase value that keep track of the unsent message. + NewRecord = noNewRecord; + MailSetUnsentMessage (MailDB, 0); + + if (CurrentCategory == draftCategory && *deleted) + MessagesInCategory--; + + // Find the current record. + if (CurrentRecord != noRecordSelected && uniqueIdValid) + if (DmFindRecordByID (MailDB, uniqueID, &CurrentRecord) != 0) + CurrentRecord = noRecordSelected; + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: ChangeCategory + * + * DESCRIPTION: This routine updates the global varibles that keep track + * of category information. + * + * PARAMETERS: category - new category (index) + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/3/96 Initial Revision + * + ***********************************************************************/ +static void ChangeCategory (UInt16 category) +{ + MessagesInCategory = DmNumRecordsInCategory (MailDB, category); + CurrentCategory = category; + TopVisibleRecord = 0; +} + + +/*********************************************************************** + * + * FUNCTION: DrawString + * + * DESCRIPTION: This routine draws the string passed, truncating and + adding an ellipsis to the end if necessary. + * + * PARAMETERS: str - pointer to a string + * x - draw position + * y - draw position + * width - maximum width to draw. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 05/30/96 Initial Revision + * kwk 05/28/99 Revised for Int'l support. + * + ***********************************************************************/ +static void DrawString (Char * str, Int16 x, Int16 y, Int16 width) +{ + Char * eol = StrChr (str, linefeedChr); + WinDrawTruncChars (str, (eol == NULL ? StrLen (str): (Int16) (eol - str)), x, y, width); +} + + +/*********************************************************************** + * + * FUNCTION: GetSignature + * + * DESCRIPTION: This routine returns a copy of the message signature + * string. This routine allocates a new MemHandle to hold + * signature, the caller is responsible for freeing this + * MemHandle. + * + * PARAMETERS: nothing + * + * RETURNED: MemHandle of a signature or zero + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 1/24/96 Initial Revision + * + ***********************************************************************/ +static MemHandle GetSignature (void) +{ + UInt16 prefsSize; + Int16 version; + Char * p; + MemHandle h; + + // Get the length of the signature. + prefsSize = 0; + version = PrefGetAppPreferences (sysFileCMail, mailSignaturePrefID, NULL, &prefsSize, true); + if (version == noPreferenceFound) + return (0); + + // Copy the signature. + h = MemHandleNew (prefsSize); + p = MemHandleLock (h); + PrefGetAppPreferences (sysFileCMail, mailSignaturePrefID, p, &prefsSize, true); + MemPtrUnlock (p); + + return (h); +} + + +/*********************************************************************** + * + * FUNCTION: SetSignature + * + * DESCRIPTION: This routine save the passed signature to the + * applicatiion information block. + * + * PARAMETERS: dpP - database pointer + * h - MemHandle of the signature + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 1/24/96 Initial Revision + * + ***********************************************************************/ +static void SetSignature (MemHandle h) +{ + UInt32 size = 0; + Char * p = 0; + + + if (h) + { + p = MemHandleLock (h); + size = StrLen (p) + 1; + } + + PrefSetAppPreferences (sysFileCMail, mailSignaturePrefID, mailVersionNum, + p, size, true); + + if (h) + MemPtrUnlock (p); +} + + +/*********************************************************************** + * + * FUNCTION: ClearEditState + * + * DESCRIPTION: This routine take the appication out of edit mode. + * The edit state of the current record is remember until + * this routine is called. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/18/96 Initial Revision + * + ***********************************************************************/ +static void ClearEditState (void) +{ + // Clear the global variables that keeps track of the edit start of the + // current record. + ItemSelected = false; + EditPosition = 0; + EditSelectionLength = 0; + NewViewCurrentRowID = editToField; + + +} + + +/*********************************************************************** + * + * FUNCTION: PrefApply + * + * DESCRIPTION: This routine applies the changes made in the Pref Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/12/96 Initial Revision + * + ***********************************************************************/ +static void PrefApply (void) +{ + MemHandle h; + FieldPtr fld; + ControlPtr ctl; + UInt16 listItem; + + // Get the "confirm delete message" setting from the dialog box + ctl = GetObjectPtr (PrefConfirmDeleteCheckbox); + ConfirmDelete = (CtlGetValue (ctl) != 0); + + // Get the signature field. + fld = GetObjectPtr (PrefSignatureField); + if (FldDirty (fld)) + { + h = FldGetTextHandle (fld); + SetSignature (h); + } + + // Set the default mail app + if(appCnt && crIDs) + { + UInt32 crID; + + listItem = LstGetSelection(GetObjectPtr(PrefDefaultMailList)); + crID = crIDs[listItem]; + ExgSetDefaultApplication(crID, exgRegSchemeID, "mailto"); + } +} + +/*********************************************************************** + * + * FUNCTION: PrvSetMailAppsList + * + * DESCRIPTION: This routine sets or initializes the list of mail apps + * + * PARAMETERS: The list selection to make current, or -1 to get from the + * exchange manager setting. + * + * RETURNED: Nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * gcd 10/11/00 Initial Revision + ***********************************************************************/ +void PrvSetMailAppsList(Int32 listSelection) +{ + ControlPtr ctl; + ListPtr lst; + UInt32 defaultID; + + ctl = GetObjectPtr(PrefDefaultMailTrigger); + lst = GetObjectPtr(PrefDefaultMailList); + + if(!crIDs) // If we don't already have the id list + { + ExgGetRegisteredApplications(&crIDs, &appCnt, &appNames, NULL, exgRegSchemeID, "mailto"); + if(appCnt) + { + MemHandle tmpH = SysFormPointerArrayToStrings(appNames, appCnt); + if(tmpH) + appNamesArray = MemHandleLock(tmpH); + else + return; + } + else + return; + } + + if(appNamesArray) + LstSetListChoices(lst, appNamesArray, appCnt); + LstSetHeight(lst, appCnt < 6 ? appCnt : 6); + + if(listSelection == -1) + { + UInt16 i; + ExgGetDefaultApplication(&defaultID, exgRegSchemeID, "mailto"); + + for(i=0;ieType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case PrefOkButton: + PrefApply (); + FrmReturnToForm (0); +/* HandEra */ + if(vgaExists) + VgaRestoreScreenState(&gScreenState); +/* end HandEra */ + handled = true; + break; + + case PrefCancelButton: + FrmReturnToForm (0); +/* HandEra */ + if(vgaExists) + VgaRestoreScreenState(&gScreenState); +/* end HandEra */ + handled = true; + break; + } + } + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); +/* HandEra */ + if(vgaExists) + VgaSaveScreenState(&gScreenState); + ToolsVgaAdjustModalForm(frm, true); +/* end HandEra */ + PrefInit (); + FrmDrawForm (frm); + FrmSetFocus (frm, FrmGetObjectIndex (frm, PrefSignatureField)); + handled = true; + } + + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: OptionsApply + * + * DESCRIPTION: This routine applies the changes made in the Options Dialog + * (aka Preferences). + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/3/96 Initial Revision + * + ***********************************************************************/ +static void OptionsApply (void) +{ + UInt8 sortOrder; + UInt16 listItem; + ControlPtr ctl; + + // Update the sort order. Reset the To Do list to the top. + listItem = LstGetSelection (GetObjectPtr (OptionsSortByList)); + switch (listItem) + { + case sortByDateItem: sortOrder = sortByDate; break; + case sortByFromItem: sortOrder = sortByFrom; break; + case sortBySubjectItem: sortOrder = sortBySubject; break; + } + + + if (MailGetSortOrder (MailDB) != sortOrder) + { + MailChangeSortOrder (MailDB, sortOrder); + TopVisibleRecord = 0; + } + + // Show or hide the due date column. + ctl = GetObjectPtr (OptionsShowDates); + ShowDates = CtlGetValue (ctl); +} + + +/*********************************************************************** + * + * FUNCTION: OptionsInit + * + * DESCRIPTION: This routine initializes the Options Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/3/96 Initial Revision + * + ***********************************************************************/ +static void OptionsInit (void) +{ + UInt16 sortOrder; + Char * label; + ListPtr lst; + ControlPtr ctl; + + // Set the trigger and popup list that indicates the sort order. + sortOrder = MailGetSortOrder (MailDB); + + lst = GetObjectPtr (OptionsSortByList); + label = LstGetSelectionText (lst, sortOrder); + ctl = GetObjectPtr (OptionsSortByTrigger); + CtlSetLabel (ctl, label); + LstSetSelection (lst, sortOrder); + + + // Initialize the checkboxes in the dialog box. + ctl = GetObjectPtr (OptionsShowDates); + CtlSetValue (ctl, ShowDates); +} + + +/*********************************************************************** + * + * FUNCTION: OptionsHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "Options + * Dialog Box" of the Mail 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. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/3/96 Initial Revision + * + ***********************************************************************/ +static Boolean OptionsHandleEvent (EventPtr event) +{ + Boolean handled = false; + FormPtr frm; + + if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case OptionsOkButton: + OptionsApply (); + FrmReturnToForm (ListView); + FrmUpdateForm (ListView, updateDisplayOptsChanged); + handled = true; + break; + + case OptionsCancelButton: + FrmReturnToForm (ListView); + handled = true; + break; + + } + } + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); +/* HandEra */ + ToolsVgaAdjustModalForm(frm, false); +/* end HandEra */ + OptionsInit (); + FrmDrawForm (frm); + handled = true; + } + + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: ReplyFormatMessage + * + * DESCRIPTION: This routine format the message body of a reply message. + * + * PARAMETERS: recordP - message to reply to + * forward - true in forwarding the message + * + * RETURNED: true if the new message was sucessfully created. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/15/96 Initial Revision + * + ***********************************************************************/ +static Err ReplyFormatMessage (MailDBRecordPtr record, Boolean forward) +{ + Err err = 0; + Char chr; + UInt16 len; + UInt16 offset = 0; + UInt16 bufferLen; + Char * buffer; + Char * str; + Char * name; + MemHandle resH; + + if ((!*record->body) || (! IncludeOriginalText)) + return (0); + + buffer = MemHandleLock (MemHandleNew (replayBufferLen)); + + // Forwarded Message ? + if (forward) + { + // Start the message with a linefeed. + chr = linefeedChr; + err = MailInsertIntoField (MailDB, NewRecord, mailFieldBody, &chr, 1, offset); + if (err) goto exit; + offset++; + + // Prepend "-- Forwarded Message --" to the beginning of the message + // text. + resH = DmGetResource (strRsc, forwardMessageStrId); + str = MemHandleLock (resH); + len = StrLen (str); + err = MailInsertIntoField (MailDB, NewRecord, mailFieldBody, str, len, offset); + + MemHandleUnlock (resH); + offset += len; + if (err) goto exit; + } + + + else if (record->from && *record->from) + { + // Start the message with a linefeed. + chr = linefeedChr; + err = MailInsertIntoField (MailDB, NewRecord, mailFieldBody, &chr, 1, offset); + if (err) goto exit; + offset++; + + // Add the email name of the sender, formatted as: + // <> wrote on <> + + // Get the friendly name if there is one. + name = MemPtrNew (maxFriendlyNameLen); + MailParseAddress (record->from, true, name, maxFriendlyNameLen); + if (*name) + str = name; + else + str = record->from; + len = StrLen (str); + err = MailInsertIntoField (MailDB, NewRecord, mailFieldBody, str, len, offset); + MemPtrFree (name); + offset += len; + if (err) goto exit; + + + // Append the string " wrote on ". + resH = DmGetResource (strRsc, wroteOnStrId); + str = MemHandleLock (resH); + len = StrLen (str); + err = MailInsertIntoField (MailDB, NewRecord, mailFieldBody, str, len, offset); + MemHandleUnlock (resH); + offset += len; + if (err) goto exit; + + + // Add the message date, a colon and a couple of linefeeds. + DateToAscii (record->date.month, record->date.day, + (record->date.year+firstYear) % 100, DateFormat, buffer); + len = StrLen (buffer); + buffer [len++] = spaceChr; + + TimeToAscii (record->time.hours, record->time.minutes, TimeFormat, &buffer[len]); + + len = StrLen (buffer); + buffer [len++] = colonChr; + buffer [len++] = linefeedChr; + buffer [len++] = linefeedChr; + + err = MailInsertIntoField (MailDB, NewRecord, mailFieldBody, buffer, len, offset); + offset += len; + if (err) goto exit; + } + + + // Append the message body. + if (! CommentOriginalText) + { + // Add the body of the message to the forwarded message. + len = StrLen (record->body); + err = MailInsertIntoField (MailDB, NewRecord, mailFieldBody, record->body, + len, offset); + if (err) goto exit; + } + + // Comment original text. + else if (record->body) + { + bufferLen = 0; + + str = record->body; + while (true) + { + len = FntWordWrap (str, commentedMsgWidth); + + // Write the buffer if we at the end of the message or if there + // is not enought space in the buffer for the next line plus + // a ">" and a linefeed. + if ((len + bufferLen > replayBufferLen - 2) || (len == 0)) + { + err = MailInsertIntoField (MailDB, NewRecord, mailFieldBody, + buffer, bufferLen, offset); + if (err) goto exit; + offset += bufferLen; + + if (len == 0) + break; + else + bufferLen = 0; + } + + buffer[bufferLen++] = '>'; + MemMove (&buffer[bufferLen], str, len); + str += len; + bufferLen += len; + + if (buffer[bufferLen-1] != linefeedChr) + buffer[bufferLen++] = linefeedChr; + } + } + +exit: + MemPtrFree (buffer); + return (err); +} + + + +/*********************************************************************** + * + * FUNCTION: ReplyApply + * + * DESCRIPTION: This routine applies the changes made in the Reply Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: true if the new message was sucessfully created. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/15/96 Initial Revision + * + ***********************************************************************/ +static Boolean ReplyApply (void) +{ + Err err = 0; + UInt16 len; + UInt16 toID; + UInt16 size; + UInt32 uniqueID; + Char * MemPtr; + Char * prefix; + Char * to = 0; + Char * cc = 0; + Char * subject = 0; + Char * addresses; + FormPtr frm; + MemHandle resH; + MemHandle recordH; + ControlPtr ctl; + MailDBRecordType record; + + + // Save the include original text checkbox setting. + ctl = GetObjectPtr (ReplayIncludeTextCheckbox); + IncludeOriginalText = (CtlGetValue (ctl) != 0); + + // Save the comment original text checkbox setting. + ctl = GetObjectPtr (ReplyCommentTextCheckbox); + CommentOriginalText = (CtlGetValue (ctl) != 0); + + // Get the reply to setting (sender, all, or forward). + frm = FrmGetActiveForm (); + toID = FrmGetObjectId (frm, FrmGetControlGroupSelection (frm, ReplyToGroup)); + + // Create the replay message. + if (! CreateRecord ()) + return (false); + + // Get the curernt record. + err = MailGetRecord (MailDB, CurrentRecord, &record, &recordH); + ErrFatalDisplayIf (err, "Error get record"); + + // The current record may get move when we change the subject field. + DmRecordInfo (MailDB, CurrentRecord, NULL, &uniqueID, NULL); + + // Format the subject of the new message. Append the appropriate + //prefix (Re: or Fwd:) to the beginning of the subject. If the + //subject already begins with the prefix don't add it. + if (toID == ReplyForwardPushButton) + resH = DmGetResource (strRsc, forwardPrefixStrId); + else + resH = DmGetResource (strRsc, replyPrefixStrId); + prefix = MemHandleLock (resH); + + if (MemCmp (record.subject, prefix, StrLen(prefix)) == 0) + err = MailChangeRecordField (MailDB, &NewRecord, mailFieldSubject, + record.subject); + else + { + subject = MemPtrNew (StrLen(prefix) + StrLen (record.subject) + 1); + StrCopy (subject, prefix); + StrCat (subject, record.subject); + err = MailChangeRecordField (MailDB, &NewRecord, mailFieldSubject, subject); + MemPtrFree (subject); + } + MemHandleUnlock (resH); + if (err) goto errorExit; + + + // Set the "To" field of the new record. If we're replying to the sender + // or to all, then set the "To" field to the "From" field of the + // original message. If we're forwarding the message then the "To" field + // is blank. + if (toID == ReplyToSenderPushButton) + { + size = StrLen (record.from) + 1; + if (size) + { + to = MemPtrNew (size); + MailParseAddress (record.from, false, to, size); + } + } + + else if (toID == ReplyToAllPushButton) + { + size = StrLen (record.from) + StrLen (record.to) + 2; // one for linfeedand one for terminator + if (size) + { + to = MemPtrNew (size); + MailParseAddress (record.from, false, to, size); + + // Add all the addresses in the "To" field of the original message. + addresses = record.to; + MemPtr = to; + while (addresses && *addresses) + { + len = StrLen (MemPtr); + if (len) + MemPtr[len++] = linefeedChr; + size -= len; + MemPtr += len; + MailParseAddress (addresses, false, MemPtr, size); + addresses = StrChr (addresses, linefeedChr); + if (addresses) addresses++; + } + } + } + + if (to) + { + err = MailChangeRecordField (MailDB, &NewRecord, mailFieldTo, to); + MemPtrFree (to); + if (err) goto errorExit; + } + + + // Add all the addresses in the "CC" field of the original message. + if (toID == ReplyToAllPushButton && *record.cc) + { + size = StrLen (record.cc) + 1; + cc = MemPtrNew (size); + *cc = 0; + MemPtr = cc; + addresses = record.cc; + while (addresses && *addresses) + { + MailParseAddress (addresses, false, MemPtr, size); + addresses = StrChr (addresses, linefeedChr); + if (addresses) + { + addresses++; + len = StrLen (MemPtr); + MemPtr[len] = linefeedChr; + size -= len + 1; + MemPtr += len + 1; + } + } + if (cc) + { + err = MailChangeRecordField (MailDB, &NewRecord, mailFieldCC, cc); + MemPtrFree (cc); + if (err) goto errorExit; + } + } + + + // Format message body. + err = ReplyFormatMessage (&record, (toID == ReplyForwardPushButton)); + if (err) goto errorExit; + + + // Clean winUp + MemHandleUnlock (recordH); + DmFindRecordByID (MailDB, uniqueID, &CurrentRecord); + + return (true); + + +errorExit: + MemHandleUnlock (recordH); + DmFindRecordByID (MailDB, uniqueID, &CurrentRecord); + + // If the allocate failed, display a warning. + FrmAlert (DeviceFullAlert); + return (false); +} + + +/*********************************************************************** + * + * FUNCTION: ReplyInit + * + * DESCRIPTION: This routine initializes the Reply Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/15/96 Initial Revision + * + ***********************************************************************/ +static void ReplyInit (void) +{ + ControlPtr ctl; + + // Turn on the reply to send push button. + FrmSetControlGroupSelection (FrmGetActiveForm (), ReplyToGroup, + ReplyToSenderPushButton); + + // Set the include original text checkbox. + ctl = GetObjectPtr (ReplayIncludeTextCheckbox); + CtlSetValue (ctl, (IncludeOriginalText == true)); + + // Set the comment original text checkbox. + ctl = GetObjectPtr (ReplyCommentTextCheckbox); + CtlSetValue (ctl, (CommentOriginalText == true)); +} + + +/*********************************************************************** + * + * FUNCTION: ReplyHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "Reply + * Dialog Box". + * + * 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. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/15/96 Initial Revision + * + ***********************************************************************/ +static Boolean ReplyHandleEvent (EventPtr event) +{ + FormPtr frm; + Boolean handled = false; + + if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case ReplyOkButton: + if (ReplyApply ()) + { + FrmCloseAllForms (); + FrmGotoForm (NewView); + } + else + FrmReturnToForm (0); + handled = true; + break; + + case ReplyCancelButton: + FrmReturnToForm (0); + handled = true; + break; + + case ReplyForwardPushButton: + CtlSetValue (GetObjectPtr (ReplayIncludeTextCheckbox), true); +// CtlSetValue (GetObjectPtr (ReplyCommentTextCheckbox), true); + break; + + case ReplyCommentTextCheckbox: + if (event->data.ctlSelect.on) + CtlSetValue (GetObjectPtr (ReplayIncludeTextCheckbox), true); + break; + } + } + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); +/* HandEra */ + ToolsVgaAdjustModalForm(frm, false); +/* end HandEra */ + ReplyInit (); + FrmDrawForm (frm); + handled = true; + } + + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: DetailsApply + * + * DESCRIPTION: This routine applies the changes made in the Details Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: update code that is sent to the "New View". + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/11/96 Initial Revision + * + ***********************************************************************/ +static UInt16 DetailsApply (void) +{ + UInt16 updateCode = 0; + ListPtr lst; + MemHandle recordH; + ControlPtr ctl; + Boolean on; + MailFlagsType flags; + MailDBRecordType record; + + + MailGetRecord (MailDB, NewRecord, &record, &recordH); + flags = record.flags; + MemHandleUnlock (recordH); + + + // Get the priority setting from the dialog box. + lst = GetObjectPtr (DetailsPriorityList); + flags.priority = LstGetSelection (lst); + + // Get the signature setting from the dialog box + ctl = GetObjectPtr (DetailsSignatureCheckbox); + on = (CtlGetValue (ctl) != 0); + flags.signature = on; + AttachSignature = on; + + // Get the "confirm read" setting from the dialog box. + ctl = GetObjectPtr (DetailsReadCheckbox); + on = (CtlGetValue (ctl) != 0); + flags.confirmRead = on; + ConfirmRead = on; + + // Get the "confirm delivery" setting from the dialog box. + ctl = GetObjectPtr (DetailsDeliveryCheckbox); + on = (CtlGetValue (ctl) != 0); + flags.confirmDelivery = on; + ConfirmDelivery = on; + + // Update the record if necessary. + if (MemCmp (&flags, &record.flags, sizeof (MailFlagsType) != 0)) + MailChangeRecordField (MailDB, &NewRecord, mailFieldFlags, &flags); + + // Get the bcc setting + ctl = GetObjectPtr (DetailsBCCCheckbox); + on = (CtlGetValue (ctl) != 0); + + if (NewViewShowBCC != on) + updateCode = updateReinitialize; + else + updateCode = updateRestoreFocus; + NewViewShowBCC = on; + + return (updateCode); +} + + +/*********************************************************************** + * + * FUNCTION: DetailsInit + * + * DESCRIPTION: This routine initializes the Details Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/11/96 Initial Revision + * + ***********************************************************************/ +static void DetailsInit (void) +{ + UInt16 priority; + Char * label; + ListPtr lst; + MemHandle recordH; + ControlPtr ctl; + MailDBRecordType record; + + MailGetRecord (MailDB, NewRecord, &record, &recordH); + + // Set the priority + priority = record.flags.priority; + ctl = GetObjectPtr (DetailsPriorityTrigger); + lst = GetObjectPtr (DetailsPriorityList); + label = LstGetSelectionText (lst, priority); + CtlSetLabel (ctl, label); + LstSetSelection (lst, priority); + + // Set the BCC. + ctl = GetObjectPtr (DetailsBCCCheckbox); + CtlSetValue (ctl, (NewViewShowBCC == true)); + + // Set the signature checkbox. + ctl = GetObjectPtr (DetailsSignatureCheckbox); + CtlSetValue (ctl, (record.flags.signature == true)); + + // Set the "confirm read" checkbox. + ctl = GetObjectPtr (DetailsReadCheckbox); + CtlSetValue (ctl, (record.flags.confirmRead == true)); + + // Set the "confirm delivery" checkbox. + ctl = GetObjectPtr (DetailsDeliveryCheckbox); + CtlSetValue (ctl, (record.flags.confirmDelivery == true)); + + // Unlock the new message. + MemHandleUnlock (recordH); +} + + +/*********************************************************************** + * + * FUNCTION: DetailsHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "Details + * Dialog Box". + * + * 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. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/11/96 Initial Revision + * + ***********************************************************************/ +static Boolean DetailsHandleEvent (EventPtr event) +{ + UInt16 updateCode; + FormPtr frm; + Boolean handled = false; + + if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case DetailsOkButton: + updateCode = DetailsApply (); + FrmReturnToForm (NewView); +/* HandEra */ + if(vgaExists) + VgaRestoreScreenState(&gScreenState); +/* end HandEra */ + FrmUpdateForm (NewView, updateCode); + handled = true; + break; + + case DetailsCancelButton: + FrmReturnToForm (NewView); +/* HandEra */ + if(vgaExists) + VgaRestoreScreenState(&gScreenState); +/* end HandEra */ + FrmUpdateForm (NewView, updateRestoreFocus); + handled = true; + break; + } + } + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); + +/* HandEra */ + if(vgaExists) + VgaSaveScreenState(&gScreenState); + ToolsVgaAdjustModalForm(frm, true); +/* end HandEra */ + + DetailsInit (); + FrmDrawForm (frm); + handled = true; + } + + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewUpdateScrollBar + * + * DESCRIPTION: This routine update the scroll bar. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/10/96 Initial Revision + * + ***********************************************************************/ +static void EditViewUpdateScrollBar () +{ + UInt16 scrollPos; + UInt16 textHeight; + UInt16 fieldHeight; + Int16 maxValue; + FormPtr frm; + FieldPtr fld; + ScrollBarPtr bar; + + frm = FrmGetActiveForm (); + fld = GetObjectPtr (EditField); + bar = GetObjectPtr (EditScrollBar); + + FldGetScrollValues (fld, &scrollPos, &textHeight, &fieldHeight); + + if (textHeight > fieldHeight) + maxValue = textHeight - fieldHeight; + else if (scrollPos) + maxValue = scrollPos; + else + maxValue = 0; + + SclSetScrollBar (bar, scrollPos, 0, maxValue, fieldHeight-1); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewScroll + * + * DESCRIPTION: This routine scrolls the message view by the number of + * lines specified. + * + * PARAMETERS: direction - winUp or dowm + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/10/96 Initial Revision + * + ***********************************************************************/ +static void EditViewScroll (Int16 linesToScroll) +{ + FieldPtr fld; + + fld = GetObjectPtr (EditField); + + if (linesToScroll < 0) + FldScrollField (fld, -linesToScroll, winUp); + + else if (linesToScroll > 0) + FldScrollField (fld, linesToScroll, winDown); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewPageScroll + * + * DESCRIPTION: This routine scrolls the message a page winUp or winDown. + * + * PARAMETERS: direction winUp or winDown + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/10/96 Initial Revision + * + ***********************************************************************/ +static void EditViewPageScroll (WinDirectionType direction) +{ + Int16 value; + Int16 min; + Int16 max; + Int16 pageSize; + UInt16 linesToScroll; + FieldPtr fld; + ScrollBarPtr bar; + + fld = GetObjectPtr (EditField); + + if (FldScrollable (fld, direction)) + { + linesToScroll = FldGetVisibleLines (fld) - 1; + FldScrollField (fld, linesToScroll, direction); + + + // Update the scroll bar. + bar = GetObjectPtr (EditScrollBar); + SclGetScrollBar (bar, &value, &min, &max, &pageSize); + + if (direction == winUp) + value -= linesToScroll; + else + value += linesToScroll; + + SclSetScrollBar (bar, value, min, max, pageSize); + } +} + +/*********************************************************************** + * + * FUNCTION: EditViewToggleFont + * + * DESCRIPTION: This routine changes the font used to display a note. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/10/97 Change the font for the message view + * + ***********************************************************************/ +static void EditViewToggleFont () + { + FieldPtr fld; + FontID originalFont = EditFont; + + fld = GetObjectPtr (EditField); + + EditFont = FontSelect (originalFont); + + // FldSetFont will redraw the field if it is visible. + + if (EditFont != originalFont) + { + FldSetFont (fld, EditFont); + EditViewUpdateScrollBar (); + } + }//EditViewToggleFont + +/*********************************************************************** + * + * FUNCTION: EditViewSetTitle + * + * DESCRIPTION: This routine sets the title of the note view. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 06/10/96 Initial Revision + * kwk 12/11/98 Modified for int'l support. + * + ***********************************************************************/ + static void EditViewSetTitle (void) + { + Int16 i; + UInt16 len; + UInt16 width; + Int16 maxWidth; + Char * resP; + Char * title; + Char * subject; + MemHandle resH; + MemHandle recordH; + MailDBRecordType record; + + if (EditTitleH) + MemHandleFree (EditTitleH); + + EditTitleH = MemHandleNew (maxEditTitleLen + 2); + if (! EditTitleH) return; + title = MemHandleLock (EditTitleH); + + + // If we are editing the to, cc, bcc, or subject field, get the title + // from a resource. + if (EditViewField < editBodyField) + { + resH = DmGetResource (strRsc, editViewTitlesStrId); + resP = MemHandleLock (resH); + for (i = 1; i <= EditViewField; i++) + resP = StrChr (resP, commaChr) + 1; + len = (UInt16) (StrChr (resP, commaChr) - resP); + + MemMove (title, resP, len); + title[len] = 0; + MemHandleUnlock (resH); + } + + // If we're editing the body of the message then use the subject field + // as the title. Truncate the tile if it's to long. + else + { + maxWidth = maxEditTitleLenWidth; + width = 0; + *title = 0; + + // Get a pointer to the start of the requested field. + MailGetRecord (MailDB, NewRecord, &record, &recordH); + + subject = record.subject; + + if (*subject) + { + title[0] = 0; + len = 0; + while (true) + { + WChar ch; + UInt16 charSize = TxtGetNextChar (subject, len, &ch); + + if ((ch == '\0') + || (ch == linefeedChr) + || (len + charSize > maxEditTitleLen)) break; + + TxtSetNextChar (title, len, ch); + len += charSize; + title[len] = 0; + + width += FntWCharWidth (ch); + if (width >= maxWidth) break; + } + + if ((width >= maxWidth) && (subject[len] != linefeedChr)) + { + maxWidth -= FntWCharWidth (chrEllipsis); + while ((width > maxWidth) && (len > 0)) + { + WChar ch; + len -= TxtGetPreviousChar (title, len, &ch); + width -= FntWCharWidth(ch); + } + + title[len] = chrEllipsis; + title[len+1] = 0; + } + } + + else + { + subject = MemHandleLock (DmGetResource (strRsc, noSubjectStrID)); + StrCopy (title, subject); + MemPtrUnlock (subject); + } + + MemHandleUnlock (recordH); + } + + FrmSetTitle (FrmGetActiveForm (), title); + } + + +/*********************************************************************** + * + * FUNCTION: EditViewDoCommand + * + * DESCRIPTION: This routine preforms the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: true if the menu command was handled + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 1/27/97 Initial Revision + * + ***********************************************************************/ +static Boolean EditViewDoCommand (UInt16 command) +{ + FieldPtr fld; + Boolean handled = false; + + switch (command) + { + case editLookupMenuCmd: + if (EditViewField == editSubjectField || + EditViewField == editBodyField) + { + MenuEraseStatus (0); + SndPlaySystemSound (sndError); + break; + } + + fld = GetObjectPtr (EditField); + AddressLookup (fld); + handled = true; + break; + + case editChangeFontCmd: + EditViewToggleFont (); + handled = true; + break; + + } + + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewClose + * + * DESCRIPTION: This routine initializes the Edit View form. + * + * PARAMETERS: frm - pointer to the Edit View form. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/10/96 Initial Revision + * + ***********************************************************************/ +static void EditViewClose (void) +{ + UInt16 selectStart; + UInt16 selectEnd; + FieldPtr fld; + MemHandle textH; + SyncUIStatePtr stateP; + + // Release the block that holds the title. + if (EditTitleH) + { + MemHandleFree (EditTitleH); + EditTitleH = NULL; + } + + // Save the insertion point position, and length of the selection. + // We'll ues these values to restore the edit state in the New View. + fld = GetObjectPtr (EditField); + if (ItemSelected) + { + EditPosition = FldGetInsPtPosition (fld); + if (EditViewField == editBodyField) + EditBodyPosition = EditPosition; + + FldGetSelection (fld, &selectStart, &selectEnd); + EditSelectionLength = selectEnd - selectStart; + if (EditSelectionLength) + EditPosition = selectStart; + } + + + // If we're editing HotSync option, get the MemHandle of the field, the + // field routines may have allocated a new MemHandle if the passed + // MemHandle was null. + if (! EditViewEditRecord) + { + stateP = MemHandleLock (SyncUIStateH); + + textH = FldGetTextHandle (fld); + + switch (EditViewField) + { + case editToField: stateP->to = textH; break; + case editFromField: stateP->from = textH; break; + case editSubjectField: stateP->subject = textH; break; + } + + MemPtrUnlock (stateP); + } + + + // Clear the MemHandle value in the field, otherwise the MemHandle + // will be freed when the form is disposed of, this call also unlocks + // the MemHandle that contains the note string. + FldSetTextHandle (fld, 0); +} + +/* HandEra */ +/*********************************************************************** + * + * FUNCTION: EditViewResize + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static void EditViewResize(Boolean draw) +{ + Coord x,y; + FormPtr frmP; + Coord xDiff, yDiff; + Boolean drawBtn; + FieldPtr fldP; + RectangleType fldR; + RectangleType r; + + WinGetDisplayExtent(&x, &y); + + // this will get the old extent + // resize form + frmP = FrmGetActiveForm(); + FrmGetFormBounds(frmP, &r); + + xDiff = x - (r.topLeft.x + r.extent.x); + yDiff = y - (r.topLeft.y + r.extent.y); + if ((xDiff == 0) && (yDiff == 0)) + return; + + // resize form + r.extent.x += xDiff; + r.extent.y += yDiff; + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + + // Need to erase the field first, otherwise it will erase moved controls + // when shrinking it. + fldP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, EditField)); + if (draw) + FldEraseField(fldP); + + FldGetBounds(fldP, &fldR); + fldR.extent.x += xDiff; + fldR.extent.y += yDiff; + FldSetBounds(fldP, &fldR); + + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, EditDoneButton), 0, yDiff, draw); + drawBtn = (EditViewField <= editBCCField) ? draw : false; + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, EditLookupButton), 0, yDiff, draw && drawBtn); + + drawBtn = (EditViewField == editBodyField) ? draw : false; + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, EditSendButton), 0, yDiff, draw && drawBtn); + + ToolsMoveObject(frmP, ToolsFrmGetGSI(frmP), xDiff, yDiff, draw); + + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, EditScrollBar), xDiff, 0, false); + ToolsResizeObject(frmP, FrmGetObjectIndex(frmP, EditScrollBar), 0, yDiff, draw); + + if (draw) + FrmDrawForm(frmP); +} +/* end HandEra */ + +/*********************************************************************** + * + * FUNCTION: EditViewInit + * + * DESCRIPTION: This routine initializes the Edit View form. + * + * PARAMETERS: frm - pointer to the Edit View form. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/10/96 Initial Revision + * MGolden 7/7/97 removed the font butotns. added menu + * + ***********************************************************************/ +static void EditViewInit (FormPtr frm) +{ + UInt16 size; + UInt16 offset; + //UInt16 controlID; + Char * textP; + MemHandle textH; + FieldPtr fld; + MemHandle recordH; + FieldAttrType attr; + MailDBRecordType record; + SyncUIStatePtr stateP; + + + EditViewResize(false); + + fld = GetObjectPtr (EditField); + FldSetFont (fld, EditFont); + + EditViewSetTitle (); + + // Are we editing an expense record or Hotsync options. + if (EditViewEditRecord) + { + // Set the value of the edit field to the proper record field. + MailGetRecord (MailDB, NewRecord, &record, &recordH); + + switch (EditViewField) + { + case editToField: textP = record.to; break; + case editCCField: textP = record.cc; break; + case editBCCField: textP = record.bcc; break; + case editSubjectField: textP = record.subject; break; + case editBodyField: textP = record.body; break; + } + + // MailGetRecord returns a locked handle. + // We need to get the Ptr, so we lock it again, and then unlock it twice. Ick. + + offset = textP - ((Char *) MemHandleLock(recordH)); + size = StrLen (textP) + 1; // one for null terminator + MemHandleUnlock (recordH); + MemHandleUnlock (recordH); + + FldSetMaxChars (fld, maxNewFieldChars); + FldSetText (fld, recordH, offset, size); + } + + // We're editing the HotSync options + else + { + stateP = MemHandleLock (SyncUIStateH); + + switch (EditViewField) + { + case editToField: textH = stateP->to; break; + case editFromField: textH = stateP->from; break; + case editSubjectField: textH = stateP->subject; break; + } + + FldSetMaxChars (fld, maxFilterLength); + FldSetTextHandle (fld, textH); + MemPtrUnlock (stateP); + } + + + // Use the edit state from the new view. + if (ItemSelected) + { + FldSetInsPtPosition (fld, EditPosition); + if (EditSelectionLength) + FldSetSelection (fld, EditPosition, + EditPosition + EditSelectionLength); + } + + + // Have the field send event to maintain the scroll bar. + FldGetAttributes (fld, &attr); + attr.hasScrollBar = true; + + // Only the subject and message body are auto-shift fields. + if (EditViewField == editSubjectField || EditViewField == editBodyField) + attr.autoShift = true; + + FldSetAttributes (fld, &attr); + + + // If we're editing the "To", "CC" or "BCC" field then show the + // lookup button. + if (EditViewField <= editBCCField) + FrmShowObject (frm, FrmGetObjectIndex (frm, EditLookupButton)); + + // If we're editing the body of the message then shoe the send button. + if (EditViewField == editBodyField) + FrmShowObject (frm, FrmGetObjectIndex (frm, EditSendButton)); + + + // Highlight the corect font push button. +//mgmg removed the font buttons +/* + if (MessageFont == stdFont) + controlID = EditSmallFontButton; + else + controlID = EditLargeFontButton; + FrmSetControlGroupSelection (frm, EditFontGroup, controlID); +*/ + + EditViewUpdateScrollBar (); +} + + +/*********************************************************************** + * + * FUNCTION: EditViewHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "Edit View". + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handled and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/10/96 Initial Revision + * MGolden 7/7/97 Removed the font buttons...added the menu + * MGolden 7/14/947 added MessageViewCleanUpRevert + * CSS 06/22/99 Standardized keyDownEvent handling + * (TxtCharIsHardKey, commandKeyMask, etc.) + * + ***********************************************************************/ +static Boolean EditViewHandleEvent (EventPtr event) +{ + UInt32 uniqueID; + FormPtr frm; + FieldPtr fld; + Boolean deleted; + Boolean handled = false; + + if (event->eType == keyDownEvent) + { + if (TxtCharIsHardKey(event->data.keyDown.modifiers, event->data.keyDown.chr)) + { + } + else if (EvtKeydownIsVirtual(event)) + { + if (event->data.keyDown.chr == vchrPageUp) + { + EditViewPageScroll (winUp); + handled = true; + } + + else if (event->data.keyDown.chr == vchrPageDown) + { + EditViewPageScroll (winDown); + handled = true; + } + } + // Don't allow linefeeds in the subject field or in any of the filter + // fields. + else if (event->data.keyDown.chr == chrLineFeed) + { + handled = (EditViewField == editSubjectField || + (! EditViewEditRecord)); + } + } + + + else if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case EditDoneButton: + if (EditViewEditRecord) + { + RestoreFromEditView = true; + FrmGotoForm (NewView); + } + else + FrmGotoForm (SyncDialog); + handled = true; + break; + + case EditLookupButton: + fld = GetObjectPtr (EditField); + AddressLookup (fld); + handled = true; + break; + + case EditSendButton: + if (SendMessage ()) + { + RestoreFromEditView = false; + EditViewClose (); + MessageViewCleanUpRevert(); + ClearEditState (); + FrmGotoForm (ReturnToView); + } + handled = true; + break; + } + } + + else if (event->eType == menuEvent) + { + handled = EditViewDoCommand (event->data.menu.itemID); + } + + + else if (event->eType == fldChangedEvent) + { + EditViewUpdateScrollBar (); + } + + else if (event->eType == sclRepeatEvent) + { + EditViewScroll (event->data.sclRepeat.newValue - + event->data.sclRepeat.value); + } + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); + /* HandEra */ + if (vgaExists) + VgaFormModify(frm, vgaFormModify160To240); + /* end HandEra */ + EditViewInit (frm); + FrmDrawForm (frm); + FrmSetFocus (frm, FrmGetObjectIndex (frm, EditField)); + handled = true; + } + + else if (event->eType == frmSaveEvent) + { + // If we're editing an expense record then save the unique id + // of the unsent message. + if (EditViewEditRecord) + { + DmRecordInfo (MailDB, NewRecord, NULL, &uniqueID, NULL); + ClearEditState (); + EditViewClose (); + SaveDraftMessage (true, &deleted, false); + if (deleted) + uniqueID = 0; + MailSetUnsentMessage (MailDB, uniqueID); + } + } + + else if (event->eType == frmCloseEvent) + { + EditViewClose (); + } + /* HandEra */ + else if (event->eType == displayExtentChangedEvent) + { + EditViewResize(true); + handled = true; + } + /* end HandEra */ + + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewRestoreEditState + * + * DESCRIPTION: This routine restores the edit state of the new message + * view, if the view was in edit mode. This routine is + * called after returning from the details dialog + * or the edit view. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/18/96 Initial Revision + * + ***********************************************************************/ +static void NewViewRestoreEditState (void) +{ + Int16 row; + FormPtr frm; + TablePtr table; + FieldPtr fld; + FieldAttrType attr; + + + // Determine the current edit view, the lookup function need this + // value set. + switch (NewViewCurrentRowID) + { + case newToRow: EditViewField = editToField; break; + case newCCRow: EditViewField = editCCField; break; + case newBCCRow: EditViewField = editBCCField; break; + case newSubjectRow: EditViewField = editSubjectField; break; + case newBodyRow: EditViewField = editBodyField; break; + } + + // Find the row that the current record is in. Its possible + // that the current record is nolong displayable (ex: it + // was scrolled out of view). + table = GetObjectPtr (NewTable); + if ( ! TblFindRowID (table, NewViewCurrentRowID, &row) ) + { +// ClearEditState (); + return; + } + + frm = FrmGetActiveForm (); + FrmSetFocus (frm, FrmGetObjectIndex (frm, NewTable)); + TblGrabFocus (table, row, newTextColumn); + + // Restore the insertion point position. + fld = TblGetCurrentField (table); + + if (ItemSelected) + { + FldSetInsertionPoint (fld, EditPosition); + if (EditSelectionLength) + FldSetSelection (fld, EditPosition, + EditPosition + EditSelectionLength); + } + + FldGrabFocus (fld); + + + // Restore the dynamiclly resizeable attribute that + // was cleared in NewViewGetField to allow drag selection. + FldGetAttributes (fld, &attr); + attr.dynamicSize = true; + FldSetAttributes (fld, &attr); + +} + + +/*********************************************************************** + * + * FUNCTION: NewViewClearEditState + * + * DESCRIPTION: This routine clears the edit state of the to do list. + * It is caled whenever a table item is selected. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/18/96 Initial Revision + * jmp 9/29/99 Use FrmGetFormPtr() & FrmGetObjectIndex() instead of + * GetObjectPtr() because GetObjectPtr() calls FrmGetActiveForm(), + * and FrmGetActiveForm() may return a form that isn't the one we + * want when other forms are up when we are called. + * Fixes bug #22418. + * + ***********************************************************************/ +static void NewViewClearEditState (void) +{ + TablePtr table; + FormPtr frm; + + frm = FrmGetFormPtr (NewView); + table = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, NewTable)); + TblReleaseFocus (table); + ClearEditState (); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewSaveEditState + * + * DESCRIPTION: This routine is called by the table object, as a callback + * routine. We want to capture the current edit state here. + * + * PARAMETERS: table - pointer to the memo list table (TablePtr) + * row - row of the table to draw + * column - column of the table to draw + * + * RETURNED: true if the table needs to be redrawn + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/18/96 Initial Revision + * + ***********************************************************************/ +static Boolean NewViewSaveEditState (void * table, Int16 row, Int16 UNUSED_PARAM(column)) +{ + Int16 rowID; + UInt16 selectStart; + UInt16 selectEnd; + FieldPtr fld; + + fld = TblGetCurrentField (table); + + // Save the insertion point position, and length of the selection. + // We'll need the insertion point position an selection length + // if we put the table back into edit mode. + EditPosition = FldGetInsPtPosition (fld); + + FldGetSelection (fld, &selectStart, &selectEnd); + EditSelectionLength = selectEnd - selectStart; + if (EditSelectionLength) + EditPosition = selectStart; + + if (TblGetRowID (table, row) == newBodyRow) + EditBodyPosition = EditPosition; + + + if (FldDirty (fld) && (NewRecord != noNewRecord)) + DirtyRecord (NewRecord); + + + // Get the current scroll position. + rowID = TblGetRowID (table, row); + NewScrollPosition [rowID] = FldGetScrollPosition (fld); + + + return (false); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewGetField + * + * DESCRIPTION: This routine returns a pointer to a field of a mail + * record. This routine is called by the table + * object as a callback routine when it wants to display or + * edit a mail message field. + * + * PARAMETERS: table - pointer to the to do list table (TablePtr) + * row - row of the table + * column - column of the table + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 06/06/96 Initial Revision + * kwk 04/23/99 Reload fld attributes after calling FldSetScrollPosition. + * + ***********************************************************************/ +static Err NewViewGetField (void * table, Int16 row, Int16 UNUSED_PARAM(column), + Boolean editable, MemHandle *textHP, UInt16 * textOffset, UInt16 * textAllocSize, + FieldPtr fld) +{ + UInt16 rowID; + Char * textP; + MemHandle recordH; + FieldAttrType attr; + MailDBRecordType record; + + + // Get a pointer to the start of the requested field. + MailGetRecord (MailDB, NewRecord, &record, &recordH); + + rowID = TblGetRowID (table, row); + switch (rowID) + { + case newToRow: textP = record.to; break; + case newCCRow: textP = record.cc; break; + case newBCCRow: textP = record.bcc; break; + case newSubjectRow: textP = record.subject; break; + case newBodyRow: textP = record.body; break; + default: + ErrDisplay ("Invalid row"); + } + + + // Set the maximum number of characters that may be input. + FldSetMaxChars (fld, maxNewFieldChars); + + // Compute the offset within the record of the field requested, and the + // length the the field. + *textOffset = textP - ((Char *) MemHandleLock (recordH)); + *textAllocSize = StrLen (textP) + 1; // one for null terminator + *textHP = recordH; + + MemHandleUnlock (recordH); + MemHandleUnlock (recordH); + + // Normally the table object would initial the text of the current + // field, but since we want to also set the scroll position of the + // text will do it outself. The table will not initialize the field + // if it already has a text value +// if (rowID == newBodyRow) + { + FldSetText (fld, *textHP, *textOffset, *textAllocSize); + if (editable) + { + FldGetAttributes (fld, &attr); + attr.visible = false; + FldSetAttributes (fld, &attr); + + FldSetScrollPosition (fld, NewScrollPosition[rowID]); + + // Remember to reload attributes, in case they've been changed + // by the call to FldSetScrollPosition. + FldGetAttributes (fld, &attr); + attr.visible = true; + FldSetAttributes (fld, &attr); + } + else + FldSetScrollPosition (fld, NewScrollPosition[rowID]); + } + + // Set the field to support auto-shift. Only the subject and message + // body are auto-shift fields. + if (editable && (rowID == newSubjectRow || rowID == newBodyRow)) + { + FldGetAttributes (fld, &attr); + attr.autoShift = true; + FldSetAttributes (fld, &attr); + } + + + // We need to clear the dynamiclly resizeable attribute + // so that we can select text in the to, cc, bcc, and + // subject fields. These fields are resizeable but we + // limit there maximum height to a value less than the + // table routines allow, this results in the field routines + // attemping to make the field fully visible on a tblEnter + // event and preventing drag selecting. We restore the + // dynamiclly resizeable attribute after the tblEnter event + // in precessed. + if (editable && rowID != newBodyRow) + { + FldGetAttributes (fld, &attr); + attr.dynamicSize = false; + FldSetAttributes (fld, &attr); + } + + + return (0); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewDrawLabel + * + * DESCRIPTION: This routine the draw the labels in the edit view. + * This routine is called by the table routine + * TblDrawTable each time a line of the table needs to + * be drawn. + * + * PARAMETERS: table - pointer to the memo list table (TablePtr) + * row - row of the table to draw + * column - column of the table to draw + * bounds - bound to the draw region + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/6/96 Initial Revision + * + ***********************************************************************/ +static void NewViewDrawLabel (void * table, Int16 row, Int16 UNUSED_PARAM(column), + RectanglePtr bounds) +{ + Int16 i; + Int16 x; + UInt16 len; + Int16 rowID; + Int16 width; + Char ch; + FontID curFont; + Char * label; + MemHandle resH; + + rowID = TblGetRowID (table, row); + + resH = DmGetResource (strRsc, newViewLabelsStrId); + label = MemHandleLock (resH); + for (i = 1; i <= rowID; i++) + label = StrChr (label, commaChr) + 1; + len = (UInt16) (StrChr (label, commaChr) - label); + + /* HandEra */ + if ((vgaExists) && VgaIsVgaFont(EditFont)) + curFont = FntSetFont (VgaBaseToVgaFont(stdFont)); + else + curFont = FntSetFont (stdFont); + /* end HandEra */ + + width = FntCharsWidth (label, len); + x = bounds->topLeft.x + bounds->extent.x - width - FntCharWidth (colonChr); + WinDrawChars (label, len, x, bounds->topLeft.y); + x += width; + + ch = colonChr; + WinDrawChars (&ch, 1, x, bounds->topLeft.y); + + FntSetFont (curFont); + + MemHandleUnlock (resH); +} + + +/*********************************************************************** + * + * FUNCTION: MessageViewNextMessage + * + * DESCRIPTION: This routine displays the next mail message. If the + * last message in the category is currently displayed then + * the first message is shown. + * + * PARAMETERS: direction to find the next message + * + * RETURNED: true if a message is found + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/12/96 Initial Revision + * roger 6/17/97 Added scrolling backwards + * + ***********************************************************************/ +static Boolean MessageViewNextMessage (Int16 direction) +{ + UInt16 recordNum; + Boolean messageFound; + + // Find the next record + recordNum = CurrentRecord; + messageFound = SeekRecord (&recordNum, 1, direction); + + if (!messageFound && MessagesInCategory > 1) + { + if (direction == dmSeekBackward) + { + //go to the last record in the category + //we are at the first record, seek MessagesInCategory - 1 records forward + messageFound = SeekRecord (&recordNum, MessagesInCategory - 1, dmSeekForward); + } + else + { + //go to the first record in the category + //we are at the last record, seek MessagesInCategory - 1 records backwards + messageFound = SeekRecord (&recordNum, MessagesInCategory - 1, dmSeekBackward); + } + } + + if (messageFound) + { + CurrentRecord = recordNum; +//update the buttons +//mgmg mg add this code + MessageViewEnableButtons(FrmGetActiveForm ()); +//end code + MessageViewDrawMessage (); + } + + return messageFound; +} + + +/*********************************************************************** + * + * FUNCTION: NewViewUpdateScrollBar + * + * DESCRIPTION: This routine visually updates the new message view's scroll + * bar. + * + * PARAMETERS: table - pointer to the new message tabel + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 12/12/96 Initial Revision + * + ***********************************************************************/ +static void NewViewUpdateScrollBar (void) +{ + UInt16 width; + UInt16 lines; + Int16 rowID; + UInt16 pos; + Int16 rowLines; + UInt16 maxLines; + Int16 row, column; + Int16 pageSize; + Int16 maxValue; + FontID currFont; + Char * textP; + TablePtr table; + FieldPtr fld; + MemHandle recordH; + ScrollBarPtr bar; + RectangleType r; + MailDBRecordType record; + + currFont = FntSetFont (EditFont); + + table = GetObjectPtr (NewTable); + + + // Copute the page size, + TblGetBounds (table, &r); + pageSize = (r.extent.y / FntLineHeight ()) - 1; + + + // Compute the height of all the rows + MailGetRecord (MailDB, NewRecord, &record, &recordH); + width = TblGetColumnWidth (table, newTextColumn); + + + // If we're editing the body field then get scroll position within the + // body text. + if (TblEditing(table)) + { + TblGetSelection (table, &row, &column); + if (TblGetRowID (table, row) == newBodyRow) + { + fld = TblGetCurrentField (table); + NewScrollPosition [newBodyRow] = FldGetScrollPosition (fld); + } + } + + + // Get the scroll values of the body row. + FntGetScrollValues (record.body, width, NewScrollPosition [newBodyRow], + &lines, &pos); + TblFindRowID (table, newBodyRow, &row); + rowLines = TblGetRowHeight (table, row) / FntLineHeight (); + + + /* CS2 (43540): The scroll logic is a little odd, but it makes sense once you think + about it. Here goes. The body field can be autoscrolled, if you drag across it. + When this happens, it does -not- resize in the message form. Therefore, we don't + want to count the lines that are scrolled out of view when we're calculating the + scroll bar values. -However-, if the body field is the topmost displayed row in + the table, then when you scroll up, you will scroll up through the body field + first, then the rows above it will be added to the table once you reach the top. + SO, if the body field is not the top row, we subtract off the number of lines + currently scrolled out of view from the total number of lines. Whew. + */ + //if ( 0 != row ) + // { + // lines -= pos; + // pos = 0; + // } + + + lines = max (lines, rowLines); + + + for (rowID = newToRow; rowID < newBodyRow; rowID++) + { + if (rowID == newBCCRow && (! NewViewShowBCC)) + continue; + + //is the row visible? + if (TblFindRowID (table, rowID, &row)) + { + rowLines = TblGetRowHeight (table, row) / FntLineHeight (); + } + else + { + switch (rowID) + { + case newToRow: + textP = record.to; + maxLines = maxNewAddressLines; + break; + case newCCRow: + textP = record.cc; + maxLines = maxNewAddressLines; + break; + case newBCCRow: + textP = record.bcc; + maxLines = maxNewAddressLines; + break; + case newSubjectRow: + textP = record.subject; + maxLines = maxNewSubjectLines; + break; + } + rowLines = min (FldCalcFieldHeight (textP, width), maxLines); + pos += rowLines; + } + + lines += rowLines; + } + + + if (lines > pageSize + 1) + { + maxValue = lines - pageSize - 1; + } + else + { + maxValue = 0; + pos = 0; + } + + + bar = GetObjectPtr (NewScrollBar); + SclSetScrollBar (bar, pos, 0, maxValue, pageSize); + + MemHandleUnlock (recordH); + FntSetFont (currFont); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewScroll + * + * DESCRIPTION: This routine scrolls the new message view. It is called + * when the scroll bar sends a scroll event or when the + * winUp or doww button is pressed. + * + * PARAMETERS: linesToScroll - line to scroll, if < 0 then scroll winUp, + * if > 0 then scroll winDown. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/17/96 Initial Revision + * + ***********************************************************************/ +static void NewViewScroll (Int16 linesToScroll) +{ + Int16 i; + Int16 row; + UInt16 lines; + UInt16 rowID; + Int16 width; + Int16 length; + Int16 height; + Int16 columnWidth; + Int16 value; + Int16 minValue; + Int16 maxValue, maxDelta; + Int16 pageSize; + FontID currFont; + Char * chars; + TablePtr table; + MemHandle recordH; + ScrollBarPtr bar; + RectangleType r; + MailDBRecordType record; + + currFont = FntSetFont (EditFont); + + table = GetObjectPtr (NewTable); + + TblReleaseFocus (table); + + MailGetRecord (MailDB, NewRecord, &record, &recordH); + + rowID = TblGetRowID (table, 0); + + columnWidth = TblGetColumnWidth (table, newTextColumn); + + maxDelta = 0; + + // Scroll winUp. + if (linesToScroll < 0) + { + if (rowID == newBodyRow && NewScrollPosition [newBodyRow]) + { + lines = -linesToScroll; + FntWordWrapReverseNLines (record.body, columnWidth, &lines, + &NewScrollPosition [newBodyRow]); + linesToScroll += lines; + } + + while (linesToScroll < 0 && rowID> newToRow) + { + TblInsertRow (table, 0); + if (rowID-1 == newBCCRow && (! NewViewShowBCC)) + rowID -= 2; + else + rowID--; + + height = NewViewGetFieldHeight (NewRecord, rowID, columnWidth); + NewViewInitRow (table, 0, rowID, height); + + linesToScroll += height / FntLineHeight(); + } + } + + + + // Scroll winDown. + else if (linesToScroll > 0) + { + while (linesToScroll > 0 && rowID < newBodyRow) + { + height = TblGetRowHeight (table, 0); + TblRemoveRow (table, 0); + linesToScroll -= height / FntLineHeight ();; + rowID++; + if (rowID == newBCCRow && (! NewViewShowBCC)) + rowID++; + + /* CS2 (43540): While scrolling down, if we cause the body row to hit the top, + we have to resynch the scroll bar, because when we start scrolling back up, + we will go through the body field first. If the body field happens to be + scrolled, this will cause the scrollbar to jump and the thumb to resize. + Looks odd, but it keeps things in synch. + */ + if ( newBodyRow == rowID ) + { + maxDelta = NewScrollPosition[newBodyRow]; + } + } + + if (linesToScroll > 0) + { + width = TblGetColumnWidth (table, newTextColumn); + while (linesToScroll) + { + chars = &record.body[NewScrollPosition [newBodyRow]]; + length = FntWordWrap (chars, width); + if (! length) break; + + NewScrollPosition [newBodyRow] += length; + linesToScroll--; + } + + TblMarkRowInvalid (table, 0); + } + } + + MemHandleUnlock (recordH); + + + // Reinitialize the message row so that it has the correct height. + TblFindRowID (table, newBodyRow, &row); + TblGetBounds (table, &r); + height = r.extent.y; + for (i = 0; i < row; i++) + height -= TblGetRowHeight (table, i); + NewViewInitRow (table, row, newBodyRow, height); + + if ( 0 != maxDelta ) + { + /* CS2 (43540): Do the complete job of recalculating the scroll bar. */ + NewViewUpdateScrollBar(); + } + // The "to", "cc", "bcc", and "subject" fields alway scroll there entire + // height when moved on or off the display. This causes the scroll bar + // to be out of sync with what is displayed. + else if ( linesToScroll != 0 ) + { + bar = GetObjectPtr (NewScrollBar); + SclGetScrollBar (bar, &value, &minValue, &maxValue, &pageSize); + value -= linesToScroll; + SclSetScrollBar (bar, value, minValue, maxValue, pageSize); + } + + + TblMarkTableInvalid (table); + TblRedrawTable (table); + + FntSetFont (currFont); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewPageScroll + * + * DESCRIPTION: This routine scrolls the message creation view winUp + * or winDown by a page. + * + * PARAMETERS: direction winUp or winDown + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 11/14/96 Initial Revision + * + ***********************************************************************/ +static void NewViewPageScroll (WinDirectionType direction) +{ + UInt16 linesToScroll; + Int16 value; + Int16 minValue; + Int16 maxValue; + Int16 pageSize; + FontID currFont; + TablePtr table; + ScrollBarPtr bar; + RectangleType r; + + + // Determine if we should scroll at all. + bar = GetObjectPtr (NewScrollBar); + SclGetScrollBar (bar, &value, &minValue, &maxValue, &pageSize); + if (direction == winUp) + { + if (value == minValue) + return; + } + else + { + if (value == maxValue) + return; + } + + + // Copute the page size, + currFont = FntSetFont (EditFont); + table = GetObjectPtr (NewTable); + TblGetBounds (table, &r); + pageSize = (r.extent.y / FntLineHeight ()); + FntSetFont (currFont); + + + // Scroll the view. + linesToScroll = pageSize - 1; + if (direction == winUp) + { + if (linesToScroll > value - minValue) + linesToScroll = value - minValue; + linesToScroll = -linesToScroll; + } + else + { + if (linesToScroll > maxValue - value) + linesToScroll = maxValue - value; + } + NewViewScroll (linesToScroll); + + NewViewRestoreEditState (); + + // Update the scroll bar. + value += linesToScroll; + SclSetScrollBar (bar, value, minValue, maxValue, pageSize); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewNextField + * + * DESCRIPTION: If a field is being edited, advance the focus to the + * next or previous field in the table. + * + * PARAMETERS: direction - winDown (next) or winUp (previous) + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/27/95 Initial Revision + * + ***********************************************************************/ +static void NewViewNextField (WinDirectionType direction) +{ + Int16 row; + Int16 sRow; + Int16 rowID; + Int16 column; + TablePtr table; + FieldPtr fld; + FieldAttrType attr; + UInt16 zeroRowID; + ScrollBarPtr bar; + Int16 value, min, max, pageSize; + Int16 columnWidth; + + + // Find out which field is being edited. + table = GetObjectPtr (NewTable); + if (! TblEditing (table)) + return; + + TblGetSelection (table, &row, &column); + rowID = TblGetRowID (table, row); + sRow = row; + if (direction == winDown) + { + if (rowID >= newBodyRow) + { + rowID = 0; + + //find the rowID...the table may need to be scrolled + //get the rowID of the 0 row. then figure out how many to scroll + zeroRowID = TblGetRowID (table, sRow); + sRow = newToRow - zeroRowID; + + bar = GetObjectPtr (NewScrollBar); + SclGetScrollBar (bar, &value, &min, &max , &pageSize); + if (max > 0) + { + sRow = value * -1; + } + //add the number of lines of body that is above the screen + //mgmgmg + } + else + { + row++; + sRow = row; + } + } + else //UP + { + //if the row id is 0 then we want to wrap around and select the body row... + if (rowID == 0) + { + TblFindRowID (table, newBodyRow, &row); + sRow = row; + } + else if (rowID >= newBodyRow) + { + //is the subject row visible? + TblFindRowID (table, newSubjectRow, &row); + row = TblGetRowID (table, row); + if (row == newSubjectRow) + { + //yes + sRow --; + } + else + { + //subject is not visible...how far winUp is it? + bar = GetObjectPtr (NewScrollBar); + SclGetScrollBar (bar, &value, &min, &max , &pageSize); + columnWidth = TblGetColumnWidth (table, newTextColumn); + + value -= NewViewGetLineCount (NewRecord, newToRow, columnWidth); + value -= NewViewGetLineCount (NewRecord, newCCRow, columnWidth); + value -= NewViewGetLineCount (NewRecord, newSubjectRow, columnWidth); + if (NewViewShowBCC) + value -= NewViewGetLineCount (NewRecord, newBCCRow, columnWidth); + + sRow = (value + 1) * -1; + } + } + else + //select the previous row + sRow--; + } + + if (sRow < 0) + { + //scroll the table winUp, and select the first row + NewViewScroll (sRow); + NewViewUpdateScrollBar (); + sRow = 0; + } + + NewViewClearEditState (); + + NewViewCurrentRowID = TblGetRowID (table, sRow); + + NewViewRestoreEditState (); + + fld = TblGetCurrentField (table); + if (fld) + { + FldGetAttributes (fld, &attr); + if (! fld->attr.insPtVisible) + { + FldMakeFullyVisible (fld); + } + } + +/* + if (NewViewCurrentRowID == newBodyRow) + { + if (TblGetRowID (table, 0) != newBodyRow) + { + FieldPtr fld; + FieldAttrType attr; + + } + } +*/ + + + ItemSelected = true; +/* + Int16 row; + Int16 rowID; + Int16 column; + TablePtr table; + + + // Find out which field is being edited. + table = GetObjectPtr (NewTable); + if (! TblEditing (table)) + return; + + TblGetSelection (table, &row, &column); + rowID = TblGetRowID (table, row); + if (direction == winDown) + { + if (rowID >= newBodyRow) + row = 0; + else + row++; + } + else + { + if (row == 0) + TblFindRowID (table, newBodyRow, &row); + else + row--; + } + + NewViewClearEditState (); + + NewViewCurrentRowID = TblGetRowID (table, row); + + NewViewRestoreEditState (); + + ItemSelected = true; +*/ +} + + +/*********************************************************************** + * + * FUNCTION: NewViewResizeBodyField + * + * DESCRIPTION: This routine sets the height of the body field to: + * the height of the table minus the height of any other + * visible lines. + * + * PARAMETERS: table - pointer to a table object. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 12/13/96 Initial Revision + * mgolden 10/6/97 changed for the rocky fonts + * + ***********************************************************************/ +static void NewViewResizeBodyField (TablePtr table) +{ + Int16 i; + Int16 row, maxRows; + UInt16 height; + RectangleType r; + FieldPtr fld; + + //new mg + if (!TblFindRowID (table, newBodyRow, &row)) + { + //show the body field + maxRows = TblGetNumberOfRows(table); + for ( row = 0; row < maxRows; row ++) + { + if (TblGetRowID (table, row) == newBodyRow) + break; + } + if (row == maxRows) + { + //this is an error...what should we do here? + return; + } + + //set the row usable + TblSetRowUsable ( table, row, true); + } + + TblGetBounds (table, &r); + height = r.extent.y; + for (i = 0; i < row; i++) + height -= TblGetRowHeight (table, i); + + if (TblGetRowHeight (table, row) != height) + TblMarkRowInvalid (table, row); + + TblSetRowHeight (table, row, height); + + //do we need to resize the field? (only if we are editing the body!) + if (NewViewCurrentRowID == newBodyRow) + { + fld = TblGetCurrentField (table); + + if (fld->rect.extent.y != height) + { + RctCopyRectangle (&(fld->rect), &r); + r.extent.y = height; + FldSetBounds (fld, &r); + } + }//if + + //do we need to resize the field? + // + //FldSetInsPtPosition (&table->currentField, + // event->data.fldHeightChanged.currentPos); + + +} + + +/*********************************************************************** + * + * FUNCTION: NewViewResizeFieldHeight + * + * DESCRIPTION: This routine is called when the height of a line in + * the Edit View is changed as a result of user input. + * If the new height of the field is shorter, more items + * may need to be added to the top of the list. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/6/96 Initial Revision + * + ***********************************************************************/ +static void NewViewResizeFieldHeight (EventPtr event) +{ + Int16 row, i; + Int16 column; + UInt16 newRowID; + UInt16 rowID; + Int16 height; + Int16 freeSpace; + Int16 newHeight; + Int16 maxHeight; + Int16 columnWidth; + FontID currFont; + Boolean insPtState; + FieldPtr fld; + TablePtr table; + RectangleType fieldR; + + + // Get the current height of the field; + fld = event->data.fldHeightChanged.pField; + FldGetBounds (fld, &fieldR); + + // Get the id of the current row. + table = GetObjectPtr (NewTable); + TblGetSelection (table, &row, &column); + NewViewCurrentRowID = TblGetRowID (table, row); + rowID = NewViewCurrentRowID; + + columnWidth = TblGetColumnWidth (table, newTextColumn); + + // Is the field's height contracting? + if (event->data.fldHeightChanged.newHeight < fieldR.extent.y) + { + // if there are no items scrolled off the top of the table, + // scroll the text of the field winUp. + if (TblGetRowID (table, 0) == 0) + { + if (rowID == newBodyRow) + { + goto doBodyRowThing; + //return; + } + else + { + TblHandleEvent (table, event); + + // Add the freed space to the "body" field. + NewViewResizeBodyField (table); + TblRedrawTable (table); + } + } + + + // Add an item to the table to fill in the space made available by the + // shortening the field. This is because as the field shortens, we may + // now have space to show the fields above it...picture the bodfy field + // is expanded to fill the screen, as the user deletes lines, and once + // it is small enough not to fill the screen, the field dire3ctly above + // the body (the subject) should now be visible. (ie scroll into view) + else + { + freeSpace = fieldR.extent.y - event->data.fldHeightChanged.newHeight; + newRowID = TblGetRowID (table, 0); + + while (newRowID > newToRow && freeSpace) + { + // Add a row to the top of the table an initialize it. + if (newRowID-1 == newBCCRow && (! NewViewShowBCC)) + newRowID -= 2; + else + newRowID--; + height = NewViewGetFieldHeight (NewRecord, newRowID, columnWidth); + if (height > freeSpace) + break; + + // If there room to scroll a field onto the screen then do it. + TblInsertRow (table, 0); + NewViewInitRow (table, 0, newRowID, height); + + freeSpace -= height; + } + + if (freeSpace != fieldR.extent.y - event->data.fldHeightChanged.newHeight) + { + // Reinitialize the current row so that it has the correct size. + if (rowID != newBodyRow) + { + height = NewViewGetFieldHeight (NewRecord, rowID, columnWidth); + TblFindRowID (table, rowID, &row); + NewViewInitRow (table, row, rowID, height); + } + + // Add the freed space to the "body" field. + NewViewResizeBodyField (table); + + insPtState = InsPtEnabled (); + InsPtEnable (false); + + TblMarkTableInvalid (table); + TblRedrawTable (table); + + InsPtEnable (insPtState); + } + } + } + + // The field's height is expanding, have the table object resize the field. + // OR the field is the body field and we need to do the stuff below anyway. + else + { +doBodyRowThing: + + currFont = FntSetFont (EditFont); + newHeight = event->data.fldHeightChanged.newHeight; + + if (rowID == newSubjectRow) + maxHeight = maxNewSubjectLines * FntLineHeight (); + else + maxHeight = maxNewAddressLines * FntLineHeight (); + + if (rowID != newBodyRow && + newHeight > maxHeight && + TblGetRowHeight (table, row) >= maxHeight) + { + FldSetInsPtPosition (fld, event->data.fldHeightChanged.currentPos); + InsPtEnable (true); + } + else + { + if (rowID != newBodyRow && newHeight > maxHeight) + event->data.fldHeightChanged.newHeight = maxHeight; + else if (rowID == newBodyRow && row == 0) + { + //set the max height based on the font + maxHeight = table->bounds.extent.y; + + if (row == 0) + { + //get the max size of the body field + // subtract the fields above it + for (i = 0; i < row; i++) + maxHeight -= TblGetRowHeight (table, i); + } + + //is the new height larger than the size that the table want's to grow? + if (newHeight > maxHeight) + // set the new size to the max Size + event->data.fldHeightChanged.newHeight = maxHeight; + } + + //in all cases...make sure that the .newHeight is not > than the table height! + if (event->data.fldHeightChanged.newHeight > table->bounds.extent.y) + event->data.fldHeightChanged.newHeight = table->bounds.extent.y; + + TblHandleEvent (table, event); + + NewViewResizeBodyField (table); + + fld = TblGetCurrentField (table); + NewScrollPosition [rowID] = FldGetScrollPosition (fld); + + if (rowID != newBodyRow) + { + TblMarkTableInvalid (table); + TblRedrawTable (table); + } + } + FntSetFont (currFont); + } + + NewViewUpdateScrollBar (); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewItemSelected + * + * DESCRIPTION: This routine is called when an item in the new table is + * selected. + * + * 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. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * + ***********************************************************************/ +static Boolean NewViewItemSelected (EventPtr event) +{ + Int16 rowID; + TablePtr table; + Boolean handled = false; + + table = event->data.tblSelect.pTable; + rowID = TblGetRowID (table, event->data.tblSelect.row); + + + // Keep track of which row we're in with the global variable. We + // need this information to draw the correct title on view such as + // the Lookup View. + switch (rowID) + { + case newToRow: EditViewField = editToField; break; + case newCCRow: EditViewField = editCCField; break; + case newBCCRow: EditViewField = editBCCField; break; + case newSubjectRow: EditViewField = editSubjectField; break; + case newBodyRow: EditViewField = editBodyField; break; + } + + + // If we've changed row then store the new row in a global variable, + // we need this information so that we can later restore the edit + // state of the tabe. + // If the item selected is a label clear the edit state. + if (NewViewCurrentRowID != rowID) + { + if (event->data.tblSelect.column == newLabelColumn) + { + ClearEditState (); + NewViewCurrentRowID = rowID; + if (rowID != newBodyRow) + NewViewRestoreEditState (); + else + { + EditPosition = EditBodyPosition; + EditSelectionLength = 0; + } + } + else + NewViewCurrentRowID = rowID; + } + + + if (event->data.tblSelect.column == newLabelColumn) + { + + EditViewEditRecord = true; + FrmGotoForm (EditView); + handled = true; + } + + ItemSelected = true; + + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewDoCommand + * + * DESCRIPTION: This routine preforms the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: true if the menu command was handled + * + * HISTORY: + * 06/26/96 art Created by Art Lamb. + * 08/28/00 kwk Use new FrmGetActiveField trap. + * + ***********************************************************************/ +static Boolean NewViewDoCommand (UInt16 command) +{ + Int16 row; + Int16 column; + Boolean deleted; + FieldPtr fld; + TablePtr table; + Boolean handled = true; + + switch (command) + { + case newSaveDraftMenuCmd: + NewViewClearEditState (); + if (SaveDraftMessage (true, &deleted, true)) + //mgmg + //FrmGotoForm (ListView); + FrmGotoForm (ReturnToView); + break; + + case newLookupMenuCmd: + table = GetObjectPtr (NewTable); + if (TblEditing (table)) + { + TblGetSelection (table, &row, &column); + switch (TblGetRowID (table, row)) + { + case newToRow: + case newCCRow: + case newBCCRow: + fld = FrmGetActiveField (NULL); + AddressLookup (fld); + break; + + default: + SndPlaySystemSound (sndError); + } + } + else + SndPlaySystemSound (sndError); + break; + + case newPreferencesMenuCmd: + FrmPopupForm (PrefDialog); + break; + + case newHotSyncMenuCmd: + FrmPopupForm (SyncDialog); + break; + + case newPurgeMenuCmd: + PurgeDeletedRecord (); + break; + + case newAboutMenuCmd: + AbtShowAbout (sysFileCMail); + break; + + case newChangeFontMenuCmd: + NewViewToggleFont(); + break; + + default: + handled = false; + } + + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewGetLineCount + * + * DESCRIPTION: This routine returns the height, in # of rows, of a field + * in a mail message. + * + * PARAMETERS: recordNum - record index + * width - width of description + * + * RETURNED: height in pixels + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 11/28/96 Initial Revision + * + ***********************************************************************/ +static UInt16 NewViewGetLineCount (UInt16 recordNum, Int16 rowID, UInt16 width) +{ + UInt16 height; + UInt16 maxLines; + FontID curFont; + Char * textP; + MemHandle recordH; + MailDBRecordType record; + + MailGetRecord (MailDB, recordNum, &record, &recordH); + ErrFatalDisplayIf ((! recordH), "Record not found"); + + // Compute the height of the to do item's description. + curFont = FntSetFont (EditFont); + + switch (rowID) + { + case newToRow: + textP = record.to; + maxLines = maxNewAddressLines; + break; + + case newCCRow: + textP = record.cc; + maxLines = maxNewAddressLines; + break; + + case newBCCRow: + textP = record.bcc; + maxLines = maxNewAddressLines; + break; + + case newSubjectRow: + textP = record.subject; + maxLines = maxNewSubjectLines; + break; + + case newBodyRow: + textP = record.body; + maxLines = maxFieldLines; + break; + } + + height = FldCalcFieldHeight (textP, width); + height = min (height, maxLines); + + FntSetFont (curFont); + + MemHandleUnlock (recordH); + + return (height); +} + +/*********************************************************************** + * + * FUNCTION: NewViewGetFieldHeight + * + * DESCRIPTION: This routine returns the height, in pixels, of a field + * in a mail message. + * + * PARAMETERS: recordNum - record index + * width - width of description + * + * RETURNED: height in pixels + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 11/28/96 Initial Revision + * + ***********************************************************************/ +static UInt16 NewViewGetFieldHeight (UInt16 recordNum, Int16 rowID, UInt16 width) +{ + UInt16 height; + UInt16 maxLines; + FontID curFont; + Char * textP; + MemHandle recordH; + MailDBRecordType record; + + MailGetRecord (MailDB, recordNum, &record, &recordH); + ErrFatalDisplayIf ((! recordH), "Record not found"); + + // Compute the height of the to do item's description. + curFont = FntSetFont (EditFont); + + switch (rowID) + { + case newToRow: + textP = record.to; + maxLines = maxNewAddressLines; + break; + + case newCCRow: + textP = record.cc; + maxLines = maxNewAddressLines; + break; + + case newBCCRow: + textP = record.bcc; + maxLines = maxNewAddressLines; + break; + + case newSubjectRow: + textP = record.subject; + maxLines = maxNewSubjectLines; + break; + + case newBodyRow: + textP = record.body; + maxLines = maxFieldLines; + break; + } + + height = FldCalcFieldHeight (textP, width); + height = min (height, maxLines); + height *= FntLineHeight (); + + FntSetFont (curFont); + + MemHandleUnlock (recordH); + + return (height); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewHandleKey + * + * DESCRIPTION: This routine handles special processing of key events + * in the New View. If a key event is received while the + * body field has the focus and the insertion point in not + * visible, then the table needs to be scrolled + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handled and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 12/15/96 Initial Revision + * + ***********************************************************************/ +static Boolean NewViewHandleKey (EventPtr event) +{ + Boolean handled = false; + FieldPtr fld; + TablePtr table; + FieldAttrType attr; + + if (TxtCharIsHardKey(event->data.keyDown.modifiers, event->data.keyDown.chr)) + return (false); + + if (NewViewCurrentRowID == newBodyRow) + { + table = GetObjectPtr (NewTable); + if (TblGetRowID (table, 0) != newBodyRow) + { + fld = TblGetCurrentField (table); + if (fld) + { + FldGetAttributes (fld, &attr); + if ( ! fld->attr.insPtVisible) + { + if (FldMakeFullyVisible (fld)) + { + handled = true; + EvtAddEventToQueue (event); + } + } + } + } + } + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: NewViewInitRow + * + * DESCRIPTION: This routine initializes a row of the "Edit View" table. + * + * PARAMETERS: table - pointer to a table object + * row - row to initialize + * rowID - id of row + * height - row height in pixels + * + * RETURNED: tnothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/6/96 Initial Revision + * MGolden 10/3/97 added rocky font code + * + ***********************************************************************/ +static void NewViewInitRow (TablePtr table, Int16 row, Int16 rowID, UInt16 height) +{ + + TblSetItemStyle (table, row, newLabelColumn, customTableItem); + TblSetItemStyle (table, row, newTextColumn, textTableItem); + + + TblSetRowUsable (table, row, true); + + TblSetRowID (table, row, rowID); + + TblSetRowHeight (table, row, height); + + // font code + TblSetItemFont (table, row, newLabelColumn, stdFont); + TblSetItemFont (table, row, newTextColumn, EditFont); +} + + +/* TRG */ +/*********************************************************************** + * + * FUNCTION: NewViewResize + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static void NewViewResize(Boolean draw) +{ + FormPtr frmP; + Coord xDiff, yDiff; + Coord x,y; + TablePtr tableP; + Boolean editing; + RectangleType r; + + WinGetDisplayExtent(&x, &y); + + // this will get the old extent + // resize form + frmP = FrmGetActiveForm(); + FrmGetFormBounds(frmP, &r); + + xDiff = x - (r.topLeft.x + r.extent.x); + yDiff = y - (r.topLeft.y + r.extent.y); + if ((xDiff == 0) && (yDiff == 0)) + return; + + // resize form + r.extent.x += xDiff; + r.extent.y += yDiff; + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + + + // Need to erase the table first, otherwise it will erase moved controls + // when shrinking it. Also, FrmHideObject doesn't do anything for tables. + tableP = FrmGetObjectPtr(frmP, FrmGetObjectIndex(frmP, NewTable)); + editing = TblEditing(tableP); + if (draw) + { + TblReleaseFocus(tableP); + TblEraseTable(tableP); + } + + TblGetBounds(tableP, &r); + r.extent.x += xDiff; + r.extent.y += yDiff; + gNewViewTableHeight = r.extent.y; + TblSetBounds(tableP, &r); + +// x = TblGetColumnWidth(tableP, newTextColumn); +// TblSetColumnWidth(tableP, newTextColumn, x + xDiff); + TblSetColumnWidth(tableP, newTextColumn, r.extent.x - (TblGetColumnWidth(tableP, newLabelColumn) + spaceAfterLabel)); + + if(draw && (yDiff < 0)) + { + r.topLeft.y = (r.topLeft.y + r.extent.y); + r.extent.y = -yDiff; + WinEraseRectangle (&r, 0); + } + + + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, NewSendButton), 0, yDiff, draw); + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, NewCancelButton), 0, yDiff, draw); + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, NewDetailsButton), 0, yDiff, draw); + + ToolsMoveObject(frmP, ToolsFrmGetGSI(frmP), xDiff, yDiff, draw); + + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, NewScrollBar), xDiff, 0, false); + ToolsResizeObject(frmP, FrmGetObjectIndex(frmP, NewScrollBar), 0, yDiff, draw); + + if (draw) + { + NewViewLoadTable(frmP); + FrmDrawForm(frmP); + if (editing) + NewViewRestoreEditState(); + } + +} +/* end TRG */ + +/*********************************************************************** + * + * FUNCTION: NewViewInit + * + * DESCRIPTION: This routine initializes the "Edit View" of the + * Mail application. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has MemHandle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/5/96 Initial Revision + * MGolden 7/7/97 add some space after the label column + * mgolden 10/6/97 changed for the rocky fonts + * + ***********************************************************************/ +static void NewViewInit (FormPtr frm) +{ + MemHandle recordH; + MailDBRecordType record; + TablePtr table; + + NewViewResize(false); + + MailGetRecord (MailDB, NewRecord, &record, &recordH); + + if (RestoreFromEditView) + { + //check the stashed NewViewShowBCC + NewViewShowBCC = StashedNewViewShowBCC; + RestoreFromEditView = false; + } + + + // If the record has a BCC field, make sure it is visible. + if (!NewViewShowBCC) + { + NewViewShowBCC = (*record.bcc != 0); + } + + // If we'er replying to or forwarding a message then set the insertion + // point's position in the body field to the start of the text, otherwise + // place the insertion point at the end. + if (CurrentCategory == inboxCategory || CurrentCategory == filedCategory) + EditBodyPosition = 0; + else + EditBodyPosition = StrLen (record.body); + + MemHandleUnlock (recordH); + + //remember the table height... + table = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, NewTable)); + gNewViewTableHeight = table->bounds.extent.y; + + NewViewLoadTable(frm); + } + +/*********************************************************************** + * + * FUNCTION: NewViewLoadTable + * + * DESCRIPTION: Loads the rows of the table (broken out from NewViewInit) + * so the change font code can re-load the table + * + * PARAMETERS: FormPtr + * + * RETURNED: nothing. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 10/6/97 initial revision + * mgolden 10/6/97 changed for the rocky fonts + * + ***********************************************************************/ +static void NewViewLoadTable(FormPtr frm) + { + Int16 i; + Int16 row; + Int16 rowID; + UInt16 height; + UInt16 bodyHeight; + Int16 columnWidth; + Int16 rowsInTable; + TablePtr table; + RectangleType tableR; + FontID currFont; + + table = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, NewTable)); + + /* HandEra */ + if (vgaExists) + VgaTableUseBaseFont(table, !VgaIsVgaFont(EditFont)); + /* end HandEra */ + + //set the bounds of the table, to a direct multiple of the current fontHeight + currFont = FntSetFont (EditFont); + table->bounds.extent.y = (gNewViewTableHeight / FntLineHeight ()) * FntLineHeight (); + FntSetFont (currFont); + + columnWidth = TblGetColumnWidth (table, newTextColumn); + TblGetBounds (table, &tableR); + bodyHeight = tableR.extent.y; + + rowID = newToRow; + + //rowsInTable = NewViewNumberOfRows (table); + rowsInTable = TblGetNumberOfRows (table); + for (row = 0; row < rowsInTable; row++) + { + if (rowID <= newBodyRow) + { + if (rowID < newBodyRow) + { + height = NewViewGetFieldHeight (NewRecord, rowID, columnWidth); + bodyHeight -= height; + } + else + height = bodyHeight; + + NewViewInitRow (table, row, rowID, height); + + if (rowID+1 == newBCCRow && (! NewViewShowBCC)) + rowID += 2; + else + rowID++; + } + else + TblSetRowUsable (table, row, false); + } + + TblSetColumnUsable (table, newLabelColumn, true); + TblSetColumnUsable (table, newTextColumn, true); + + // add some space after the label column + TblSetColumnSpacing (table, newLabelColumn, spaceAfterLabel); + + // Set the callback routine that will draw the labels. + TblSetCustomDrawProcedure (table, newLabelColumn, NewViewDrawLabel); + + // Set the callback routines that will load and save fields + // of the mail message. + TblSetLoadDataProcedure (table, newTextColumn, (TableLoadDataFuncPtr) NewViewGetField); + TblSetSaveDataProcedure (table, newTextColumn, (TableSaveDataFuncPtr) NewViewSaveEditState); + + TblHasScrollBar (table, true); + + //init the scroll position + for (i = newToRow; i <= newBodyRow; i++) + NewScrollPosition [i] = 0; + + NewViewUpdateScrollBar (); + } + +/*********************************************************************** + * + * FUNCTION: NewViewHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "Edit View" + * of the Mail 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. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/5/96 Initial Revision + * MGolden 7/14/947 added MessageViewCleanUpRevert + * CSS 06/22/99 Standardized keyDownEvent handling + * (TxtCharIsHardKey, commandKeyMask, etc.) + * + ***********************************************************************/ +static Boolean NewViewHandleEvent (EventPtr event) +{ + UInt32 uniqueID; + FormPtr frm; + FieldPtr fld; + TablePtr table; + Boolean deleted; + Boolean handled = false; + FieldAttrType attr; + + + if (event->eType == keyDownEvent) + { + if (TxtCharIsHardKey(event->data.keyDown.modifiers, event->data.keyDown.chr)) + { + } + else if (EvtKeydownIsVirtual(event)) + { + // Scroll winUp key presed? + if (event->data.keyDown.chr == vchrPageUp) + { + NewViewPageScroll (winUp); + handled = true; + } + + // Scroll winDown key presed? + else if (event->data.keyDown.chr == vchrPageDown) + { + NewViewPageScroll (winDown); + handled = true; + } + + // Move the focus to the next field ? + else if (event->data.keyDown.chr == vchrNextField) + { + NewViewNextField (winDown); + handled = true; + } + + // Move the focus to the previous field ? + else if (event->data.keyDown.chr == vchrPrevField) + { + NewViewNextField (winUp); + handled = true; + } + + // DOLATER CSS - Figure out if we still need to call this guy to + // process other virtual characters. + else + handled = NewViewHandleKey (event); + } + + // Don't allow linefeeds in the subject field. + else if (event->data.keyDown.chr == chrLineFeed) + handled = (NewViewCurrentRowID == newSubjectRow); + + else + handled = NewViewHandleKey (event); + } + + + else if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case NewSendButton: + if (SendMessage ()) + { + MessageViewCleanUpRevert(); + ClearEditState (); + FrmGotoForm (ReturnToView); + } + else + { + FrmUpdateForm (NewView, updateReinitialize); + } + handled = true; + break; + + case NewCancelButton: + if (SaveDraftMessage (false, &deleted, false)) + { + MessageViewCleanUpRevert(); + ClearEditState (); + FrmGotoForm (ReturnToView); + } + else + NewViewRestoreEditState (); + handled = true; + break; + + case NewDetailsButton: + FrmPopupForm (DetailsDialog); + handled = true; + break; + } + } + + + else if (event->eType == ctlExitEvent) + { + switch (event->data.ctlExit.controlID) + { + case NewSendButton: + case NewCancelButton: + case NewDetailsButton: + NewViewRestoreEditState (); + break; + } + } + + + else if (event->eType == fldHeightChangedEvent) + { + NewViewResizeFieldHeight (event); + handled = true; + } + + + else if (event->eType == fldChangedEvent) + { + NewViewUpdateScrollBar (); + handled = true; + } + + + else if (event->eType == tblEnterEvent) + { + if (event->data.tblEnter.column == newTextColumn) + { + table = event->data.tblEnter.pTable; + if (TblEditing (table)) + { + fld = TblGetCurrentField (table); + FldGetAttributes (fld, &attr); + attr.dynamicSize = false; + FldSetAttributes (fld, &attr); + } + + TblHandleEvent (table, event); + handled = true; + + // Restore the dynamiclly resizeable attribute that + // was cleared in NewViewGetField to allow drag selection. + fld = TblGetCurrentField (table); + FldGetAttributes (fld, &attr); + attr.dynamicSize = true; + FldSetAttributes (fld, &attr); + + /* CS2 (43540): when the body field is auto-scrolled, the scrollbar can get + out of synch. We can't let that happen! + */ + NewViewUpdateScrollBar(); + } + } + + + else if (event->eType == tblSelectEvent) + { + handled = NewViewItemSelected (event); + } + + + else if (event->eType == tblExitEvent) + { + NewViewRestoreEditState (); + handled = true; + } + + + else if (event->eType == menuEvent) + { + handled = NewViewDoCommand (event->data.menu.itemID); + } + + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); +/* HandEra */ + if (vgaExists) + VgaFormModify(frm, vgaFormModify160To240); +/* end HandEra */ + NewViewInit (frm); + FrmDrawForm (frm); + + NewViewRestoreEditState (); + handled = true; + } + + + else if (event->eType == frmUpdateEvent) + { + if (event->data.frmUpdate.updateCode == updateRestoreFocus) + { + NewViewRestoreEditState (); + handled = true; + } + else if (event->data.frmUpdate.updateCode == updateReinitialize) + { + frm = FrmGetActiveForm (); + table = GetObjectPtr (NewTable); + TblEraseTable (table); + ClearEditState (); + + NewViewCurrentRowID = editToField; + NewViewInit (frm); + TblDrawTable (table); + NewViewRestoreEditState (); + handled = true; + } + } + + + else if (event->eType == frmSaveEvent) + { + // Save the unique id of the unsent message if there is one. + DmRecordInfo (MailDB, NewRecord, NULL, &uniqueID, NULL); + NewViewClearEditState (); + SaveDraftMessage (true, &deleted, false); + if (deleted) + uniqueID = 0; + MailSetUnsentMessage (MailDB, uniqueID); + } + + + else if (event->eType == frmCloseEvent) + { + StashedNewViewShowBCC = NewViewShowBCC; + NewViewShowBCC = false; + } + + + else if (event->eType == sclRepeatEvent) + { + NewViewScroll (event->data.sclRepeat.newValue - + event->data.sclRepeat.value); + } + + + else if (event->eType == sclExitEvent) + { + //mgmg mg + //why is this here? + NewViewRestoreEditState (); + } +/* HandEra */ + else if (event->eType == displayExtentChangedEvent) + { + NewViewResize(true); + handled = true; + } +/* end HandEra */ + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: MessageViewMarkRead + * + * DESCRIPTION: This routine marks the current message as read. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/27/96 Initial Revision + * + ***********************************************************************/ +static void MessageViewMarkRead (void) +{ + MemHandle recordH; + MailDBRecordType record; + MailChangedFieldsType changedFields; + + + if (CurrentCategory != inboxCategory) + return; + + // Get the current record + MailGetRecord (MailDB, CurrentRecord, &record, &recordH); + + // If the current record hasn't been read yet, mark it read. + if (! record.flags.read) + { + MemHandleUnlock (recordH); + record.flags.read = true; + MemSet (&changedFields, sizeof (changedFields), 0); + changedFields.flags = true; + MailChangeRecord (MailDB, &CurrentRecord, &record, changedFields); + MailGetRecord (MailDB, CurrentRecord, &record, &recordH); + DirtyRecord (CurrentRecord); + UnreadMessages--; + } + + MemHandleUnlock (recordH); +} + +/*********************************************************************** + * + * FUNCTION: MessageViewMarkUnRead + * + * DESCRIPTION: This routine marks the current message as unread. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/10/97 Initial Revision + * + ***********************************************************************/ +static void MessageViewMarkUnRead (void) + { + MemHandle recordH; + MailDBRecordType record; + MailChangedFieldsType changedFields; + + + if (CurrentCategory != deletedCategory) + return; + + // Get the current record + MailGetRecord (MailDB, CurrentRecord, &record, &recordH); + + // If the current record hasn't been read yet, mark it read. + if (record.flags.read) + { + MemHandleUnlock (recordH); + record.flags.read = false; + MemSet (&changedFields, sizeof (changedFields), 0); + changedFields.flags = true; + MailChangeRecord (MailDB, &CurrentRecord, &record, changedFields); + MailGetRecord (MailDB, CurrentRecord, &record, &recordH); + DirtyRecord (CurrentRecord); + UnreadMessages++; + } + + MemHandleUnlock (recordH); + }//MessageViewMarkUnRead + + +/*********************************************************************** + * + * FUNCTION: MessageViewUpdateScrollBar + * + * DESCRIPTION: This routine update the scroll bar. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/4/96 Initial Revision + * + ***********************************************************************/ +static void MessageViewUpdateScrollBar (void) +{ + UInt16 topLine; + UInt16 textHeight; + UInt16 pageHeight; + Int16 maxValue; + ScrollBarPtr bar; + + bar = GetObjectPtr (MessageScrollBar); + MsgGetScrollValues (&textHeight, &pageHeight, &topLine); + + if (textHeight > pageHeight) + maxValue = textHeight - pageHeight; + else + maxValue = 0; + +//the topLine & textHeight needs to be re-caclulated! + + + + SclSetScrollBar (bar, topLine, 0, maxValue, pageHeight-1); +} + + +/*********************************************************************** + * + * FUNCTION: MessageViewScroll + * + * DESCRIPTION: This routine scrolls the message view by the number of + * lines specified. + * + * PARAMETERS: direction - winUp or dowm + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/4/96 Initial Revision + * + ***********************************************************************/ +static void MessageViewScroll (Int16 linesToScroll) +{ + if (linesToScroll < 0) + MsgScroll (-linesToScroll, winUp); + + else if (linesToScroll > 0) + MsgScroll (linesToScroll, winDown); +} + + +/*********************************************************************** + * + * FUNCTION: MessageViewPageScroll + * + * DESCRIPTION: This routine scrolls the message a page winUp or winDown + * or to the next message if scrolling past the end. + * + * PARAMETERS: direction winUp or winDown + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/4/96 Initial Revision + * roger 6/17/97 Added scrolling to the next message + * MGolden 7/28/97 Reversed rogers scroll dirctions + * + ***********************************************************************/ +static void MessageViewPageScroll (WinDirectionType direction) +{ + UInt16 objIndex; + Int16 value; + Int16 min; + Int16 max; + Int16 pageSize; + UInt16 linesToScroll; + FontID currFont; + FormPtr frm; + ScrollBarPtr bar; + RectangleType bounds; + Boolean movedToAnotherMessage; + + + // Compute the page size. + frm = FrmGetActiveForm (); + objIndex = FrmGetObjectIndex (frm, MessageGadget); + FrmGetObjectBounds (frm, objIndex, &bounds); + currFont = FntSetFont (MessageFont); + linesToScroll = (bounds.extent.y / FntLineHeight ()) - 1; + FntSetFont (currFont); + + + // Update the scroll bar. + bar = GetObjectPtr (MessageScrollBar); + SclGetScrollBar (bar, &value, &min, &max, &pageSize); + + if (direction == winUp) + { + value -= linesToScroll; + if (value < min) + { + linesToScroll -= min - value; + value = min; + } + } + else + { + value += linesToScroll; + if (value > max) + { + linesToScroll -= value - max; + value = max; + } + } + + if (linesToScroll) + { + MsgScroll (linesToScroll, direction); + SclSetScrollBar (bar, value, min, max, pageSize); + } + else + { + // Scroll to the next message + + if (direction == winUp) + movedToAnotherMessage = MessageViewNextMessage(dmSeekBackward); + else + movedToAnotherMessage = MessageViewNextMessage(dmSeekForward); + + if (movedToAnotherMessage) + SndPlaySystemSound (sndInfo); + } +} + + +/*********************************************************************** + * + * FUNCTION: MessageViewChangeHeader + * + * DESCRIPTION: This routine toggles beteewn the abbreviated and + * full header display. + * + * PARAMETERS: controlID - font button pressed (small or large). + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/4/96 Initial Revision + * + ***********************************************************************/ +static void MessageViewChangeHeader (UInt16 controlID) +{ + if (controlID == MessageFullHeaderButton) + { + ShowFullHeader = true; + MessageTopField = msgFieldTo; + } + else + { + ShowFullHeader = false; + MessageTopField = msgFieldSentTo; + } + + // Reset to the top of the message. + MessageScrollPos = 0; + + MsgErase (); + MsgDraw (); + + MessageViewUpdateScrollBar (); + + MessageViewMarkRead (); +} + + +/*********************************************************************** + * + * FUNCTION: MessageViewToggleFont + * + * DESCRIPTION: This routine changes the font used to display a note. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/79/96 Initial Revision + * + ***********************************************************************/ +static void MessageViewToggleFont () + { + FontID originalFont = MessageFont; + + MessageFont = FontSelect (originalFont); + + if (MessageFont == originalFont) + return; + + MsgChangeFont (); + + MessageViewUpdateScrollBar(); + + MessageViewMarkRead (); + + }//MessageViewToggleFont + +/*********************************************************************** + * + * FUNCTION: MessageViewSetTitle + * + * DESCRIPTION: This routine sets the title of the note view. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 06/4/96 Initial Revision + * MGolden 07/14/97 Set the title to the current category name + * Set the message x of y text + * MGolden 08/11/97 Left Justified the message next to + * the title. + * kwk 05/28/99 Use const Char* for form label text. + * kwk 06/28/99 Fixed bug w/passing obj ID vs. index to FrmGetObjectBounds + * and FrmSetObjectPosition. + * + ***********************************************************************/ + static void MessageViewSetTitle (void) + { + UInt16 len; + Char * title; + FontID currFont; + MemHandle titleH; + Char countStr [6]; + Char * titleTemplateP; + Char * tmp; + Char * MemPtr; + FormPtr frm; + Int16 total; + UInt16 labelIndex; + UInt16 titleWidth = 0; + RectangleType r; + + currFont = FntSetFont (boldFont); + + //set the title to the catgory name + titleH = MemHandleNew (dmCategoryLength); + if (titleH) + { + title = MemHandleLock (titleH); + + CategoryGetName ( MailDB, CurrentCategory, title); + + titleWidth = FntCharsWidth (title, StrLen(title)); + + FrmSetTitle (FrmGetActiveForm (), title); + } + + //free the old title MemHandle + if (MessageTitleH) + MemHandleFree (MessageTitleH); + + MessageTitleH = titleH; + + FntSetFont (currFont); + + //now set the label's "Message # of %" + titleTemplateP = MemHandleLock (DmGetResource (strRsc, MessageTitleStrID)); + + //get the position of this item in the category + StrIToA (countStr, DmPositionInCategory ( MailDB, CurrentRecord, CurrentCategory) + 1); + len = StrLen (countStr) + StrLen (titleTemplateP); + + tmp = MemPtrNew (len + 1); + ErrNonFatalDisplayIf (!tmp, "Out of memory"); + + MemPtr = StrChr (titleTemplateP, '#'); + len = MemPtr - titleTemplateP; + if (len) + StrNCopy (tmp, titleTemplateP, len); + tmp[len] = 0; + StrCat (tmp, countStr); + MemPtr++; + StrCat (tmp, MemPtr); + + //now title has the message #...add the total count of the category + total = DmNumRecordsInCategory (MailDB, CurrentCategory); + StrIToA (countStr, total); + len = StrLen (countStr) + StrLen (tmp); + + title = MemPtrNew (len + 1); + ErrFatalDisplayIf (!title, "Out of memory"); + + MemPtr = StrChr (tmp, '%'); + len = MemPtr - tmp; + if (len) + StrNCopy (title, tmp, len); + title[len] = 0; + StrCat (title, countStr); + MemPtr++; + StrCat (title, MemPtr); + + //free the tmp MemPtr + MemPtrFree(tmp); + + frm = FrmGetActiveForm (); + labelIndex = FrmGetObjectIndex(frm, MessageTitleLabel); + + // erase the old label in case it gets shorter + if (FrmVisible(frm)) + { + FrmGetObjectBounds(frm, labelIndex, &r); + WinEraseRectangle(&r, 0); + } + + //move the label if needed + if (titleWidth > 0) + FrmSetObjectPosition(frm, labelIndex, titleWidth + kMessageTitleOffset, r.topLeft.y); + + //set the label text + FrmCopyLabel ( frm, MessageTitleLabel, title); + + MemPtrUnlock(titleTemplateP); + MemPtrFree(title); + + +/* OLDWAY + Int16 maxWidth; + UInt16 len; + UInt16 width; + Char * title; + Char * subject; + FontID currFont; + MemHandle titleH; + MemHandle recordH; + MailDBRecordType record; + + currFont = FntSetFont (boldFont); + + titleH = MemHandleNew (maxMessageTitleLen + 2); + if (titleH) + { + title = MemHandleLock (titleH); + + maxWidth = maxMessageTitleLenWidth; + width = 0; + *title = 0; + + MailGetRecord (MailDB, CurrentRecord, &record, &recordH); + subject = record.subject; + + if (*subject) + { + for (len = 0; len < maxMessageTitleLen; len++) + { + if (subject[len] == linefeedChr) break; + + title[len] = subject[len]; + title[len+1] = 0; + + width += FntCharWidth (subject[len]); + if (width >= maxWidth) break; + } + + if ( (width >= maxWidth) && (subject[len] != linefeedChr) ) + { + maxWidth -= FntCharWidth (chrEllipsis); + while (width > maxWidth) + { + width -= FntCharWidth (title[len]); + len--; + } + title[len+1] = chrEllipsis; + title[len+2] = 0; + } + } + + else + { + subject = MemHandleLock (DmGetResource (strRsc, noSubjectStrID)); + StrCopy (title, subject); + MemPtrUnlock (subject); + } + + MemHandleUnlock (recordH); + + FrmSetTitle (FrmGetActiveForm (), title); + } + + if (MessageTitleH) + MemHandleFree (MessageTitleH); + + MessageTitleH = titleH; + + FntSetFont (currFont); +*/ + } + + +/*********************************************************************** + * + * FUNCTION: MessageViewDrawMessage + * + * DESCRIPTION: This routine displays the next mail message. If the + * last message in the category is currently displayed then + * the first message is shown. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/12/96 Initial Revision + * + ***********************************************************************/ +static void MessageViewDrawMessage (void) +{ + // Set and draw the title. + MessageViewSetTitle (); + + // Reset to the top of the message. + if (ShowFullHeader) + MessageTopField = msgFieldTo; + else + MessageTopField = msgFieldSentTo; + MessageScrollPos = 0; + + MessageSelectStartField = msgSelectNone; + MessageSelectEndField = msgSelectNone; + MessageSelectStartPos = 0; + MessageSelectEndPos = 0; + + + // Draw the message. + MsgErase (); + MsgDraw (); + + MessageViewUpdateScrollBar (); + + MessageViewMarkRead (); +} + + +/*********************************************************************** + * + * FUNCTION: MessageViewDeleteMessage + * + * DESCRIPTION: This routine deletes a the current message from the + * inbox. It does not delete the record from the database. + * + * PARAMETERS: nothing + * + * RETURNED: true if the message view should be exited + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/4/96 Initial Revision + * MGolden 9/97 changed the UI so that the user always go + * back to the list view after a delete. + * + ***********************************************************************/ +static Boolean MessageViewDeleteMessage (void) +{ + UInt16 attr; + UInt16 recordNum; + + if (CurrentCategory == deletedCategory) + return (false); + + if (ConfirmDelete) + { + if (FrmAlert(DeleteMessageAlert) != DeleteMessageYes) + return (false); + } + + // Move the record to the "deleted" category and mark it dirty. + DmRecordInfo (MailDB, CurrentRecord, &attr, NULL, NULL); + attr &= ~dmRecAttrCategoryMask; + attr |= deletedCategory | dmRecAttrDirty; + DmSetRecordInfo (MailDB, CurrentRecord, &attr, NULL); + + MessagesInCategory--; + ErrNonFatalDisplayIf (MessagesInCategory < 0, "invalid message count"); + + + // Find the next record + recordNum = CurrentRecord; + if (! SeekRecord (&recordNum, 0, dmSeekForward)) + { + // Find the prior record. + if (! SeekRecord (&recordNum, 0, dmSeekBackward)) + { + //mgmg + //clear the current record, we are going back to the + //list view and the current record is not in the category eny more + CurrentRecord = noRecordSelected; + return (true); + } + } + CurrentRecord = recordNum; + return true; + + //MessageViewDrawMessage (); + //return (false); + } + +/*********************************************************************** + * + * FUNCTION: MessageUndelete + * + * DESCRIPTION: Move the current message to the inbox, + * and mark it as unread. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/10/97 Initial Revision + * MGolden 7/11/97 Removed the seek next & prev since we want to just + * return to the list view. + * + ***********************************************************************/ +static Boolean MessageUndelete() + { + MemHandle recordH; + MailDBRecordType record; + UInt16 attr; + Err err = 0; + //UInt16 recordNum; + + + //get the record + MailGetRecord (MailDB, CurrentRecord, &record, &recordH); + + // Change the records category to "inbox" and mark it dirty. + DmRecordInfo (MailDB, CurrentRecord, &attr, NULL, NULL); + attr &= ~dmRecAttrCategoryMask; + attr |= inboxCategory | dmRecAttrDirty; + DmSetRecordInfo (MailDB, CurrentRecord, &attr, NULL); + + MemHandleUnlock (recordH); + + //don't mark the message unread...it will cause sync problems. + //MessageViewMarkUnRead (); + MessageViewMarkRead (); + + MessagesInCategory--; + ErrNonFatalDisplayIf (MessagesInCategory < 0, "invalid message count"); + +#ifdef NEEDED + // If the record was deleted go to the next record. If there is + // no next record go to the prior record. + recordNum = CurrentRecord; + if (! SeekRecord (&recordNum, 0, dmSeekForward)) + { + // Find the prior record. + if (! SeekRecord (&recordNum, 0, dmSeekBackward)) + return (true); + } + CurrentRecord = recordNum; + + MessageViewDrawMessage (); + + return (false); +#endif + return (true); + + //I think we should alert the users to tell them it's in the inbox now... + //Or change the category to the inbox and select this record + //MGMG + + }//MessageUndelete + +/*********************************************************************** + * + * FUNCTION: MessageViewFileMessage + * + * DESCRIPTION: This routine files a the current message, optionally + * deleting it from the inbox. It does not delete the + * record from the database. + * + * PARAMETERS: nothing + * + * RETURNED: true if the message view should be exited + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/5/96 Initial Revision + * MGolden 9/9/97 added returnToLlist bool If + * the message is changing categories, then return to the + * list view... + ***********************************************************************/ +static Boolean MessageViewFileMessage (void) +{ + Err err = 0; + UInt16 attr; + UInt16 button; + UInt16 recordNum; + Boolean copyRecord = false; + MemHandle recordH; + MailDBRecordType record; + Boolean returnToList = true; + + if (CurrentCategory == inboxCategory) + { + button = FrmAlert(FileMessageAlert); + + if (button == FileMessageCancel) + return (false); + + else if (button == FileMessageYes) + copyRecord = true; + } + + // If we're going to leave the message in the inbox, make a copy of the + // record. + if (copyRecord) + { + returnToList = false; + MailGetRecord (MailDB, CurrentRecord, &record, &recordH); + + err = MailNewRecord (MailDB, &record, &recordNum); + + MemHandleUnlock (recordH); + + if (err) + { + FrmAlert (DeviceFullAlert); + return (false); + } + } + else + recordNum = CurrentRecord; + + + // Change the records category to "filed" and mark it dirty. + DmRecordInfo (MailDB, recordNum, &attr, NULL, NULL); + attr &= ~dmRecAttrCategoryMask; + attr |= filedCategory | dmRecAttrDirty; + DmSetRecordInfo (MailDB, recordNum, &attr, NULL); + + + // If the record was deleted go to the next record. If there is + // no next record go to the prior record. + if (! copyRecord) + { + MessagesInCategory--; + ErrNonFatalDisplayIf (MessagesInCategory < 0, "invalid message count"); + + recordNum = CurrentRecord; + if (! SeekRecord (&recordNum, 0, dmSeekForward)) + { + // Find the prior record. + if (! SeekRecord (&recordNum, 0, dmSeekBackward)) + return (true); + } + CurrentRecord = recordNum; + + //we a re going to the list view, we do not need to draw the record + //MessageViewDrawMessage (); + } + + return returnToList; + } + + +/*********************************************************************** + * + * FUNCTION: MessageViewUnsendMessage + * + * DESCRIPTION: This routine removes the current message from the inbox + * and makes it an unsend message. + * + * PARAMETERS: nothing + * + * RETURNED: true if the note was deleted. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/5/96 Initial Revision + * MGolden 7/14/97 What do to if the message was in the deleted folder? + ***********************************************************************/ +static Boolean MessageViewUnsendMessage (void) + { + UInt16 attr; + + //mgmg + // if the current category is "deleted", save a copy of the message. + // Since this is called only from the edit button, it's safe to assume that if the category is filedCategory, + // then it is an editable message, not a reply ot message. + if (CurrentCategory == deletedCategory + || CurrentCategory == outboxCategory + || CurrentCategory == draftCategory + || CurrentCategory == filedCategory) + { + MessageViewInitializRevert(); + } + + + // Change the records category to "filed" and mark it dirty. + DmRecordInfo (MailDB, CurrentRecord, &attr, NULL, NULL); + attr &= ~dmRecAttrCategoryMask; + attr |= draftCategory | dmRecAttrDirty; + DmSetRecordInfo (MailDB, CurrentRecord, &attr, NULL); + + if (CurrentCategory != draftCategory) + MessagesInCategory--; + ErrNonFatalDisplayIf (MessagesInCategory < 0, "invalid message count"); + + NewRecord = CurrentRecord; + + return (true); + } + +/*********************************************************************** + * + * FUNCTION: MessageViewRevert + * + * DESCRIPTION: This routine reverts the index record to the + * global copy of the record + * + * PARAMETERS: database & current record + * + * RETURNED: error code. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/14/97 Initial Revision + ***********************************************************************/ +static Err MessageViewRevert(DmOpenRef dbP, UInt16 * index) + { + MailChangedFieldsType changedFields; + MailDBRecordType record; + MailPackedDBRecordPtr src; + Err err; + UInt16 attr; + + if (!MessageOriginalRecordData) + return -1; + + //set all of the change fields + changedFields.date = 1; + changedFields.time = 1; + changedFields.flags = 1; + changedFields.subject = 1; + changedFields.from = 1; + changedFields.to = 1; + changedFields.cc = 1; + changedFields.bcc = 1; + changedFields.replyTo = 1; + changedFields.sentTo = 1; + changedFields.body = 1; + + //unpack the record copy into a recordPtr + src = (MailPackedDBRecordPtr) MemHandleLock (MessageOriginalRecordData); + MailUnpackRecord (src, &record); + + err = MailChangeRecord (dbP, index, &record, changedFields); + MemHandleUnlock (MessageOriginalRecordData); + MemHandleFree(MessageOriginalRecordData); + MessageOriginalRecordData = NULL; + + //set the record back to the original category + DmRecordInfo (MailDB, *index, &attr, NULL, NULL); + attr &= ~(dmRecAttrCategoryMask | dmRecAttrDirty); + attr |= MessageRevertCategory; + DmSetRecordInfo (MailDB, *index, &attr, NULL); + + if (CurrentCategory != draftCategory) + MessagesInCategory ++; + + NewRecord = noNewRecord; + MailSetUnsentMessage (MailDB, 0); + + //we want to back to thelist view now... + ReturnToView = ListView; + + return err; + }//MessageViewRevert + +/*********************************************************************** + * + * FUNCTION: MessageViewInitializRevert + * + * DESCRIPTION: This routine stores a copy of the current record, in case of a revert. + * + * PARAMETERS: nothing + * + * RETURNED: error code. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/14/97 Initial Revision + ***********************************************************************/ +static void MessageViewInitializRevert() + { + MemHandle recordH; + MailDBRecordType record; + Err err; + MailPackedDBRecordPtr src, dest; + + //if there was one already, free it + if (MessageOriginalRecordData) + { + MemHandleFree(MessageOriginalRecordData); + MessageOriginalRecordData = NULL; + } + + MailGetRecord (MailDB, CurrentRecord, &record, &recordH); + + //make a copy of the record + MessageOriginalRecordData = MemHandleNew(MemHandleSize(recordH)); + MemHandleUnlock(recordH); + + //lock winDown both Handles + src = (MailPackedDBRecordPtr) MemHandleLock (recordH); + dest = (MailPackedDBRecordPtr) MemHandleLock (MessageOriginalRecordData); + + //copy the data into the new MemHandle + err = MemMove( dest, src, MemHandleSize(recordH)); + + //unlock the handles + MemHandleUnlock(recordH); + MemHandleUnlock(MessageOriginalRecordData); + + MessageRevertCategory = CurrentCategory; + }//MessageViewInitializRevert + +/*********************************************************************** + * + * FUNCTION: RestoreRevert + * + * DESCRIPTION: Find if a record was stored in the database for revert... + * It would be the only record in the ignoreCategory. If it exists, + * get a MemHandle to it's data, then remove the record. + * + * PARAMETERS: nothing + * + * RETURNED: nothing. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/14/97 Initial Revision + ***********************************************************************/ +static void RestoreRevert(Boolean keepIt) + { + UInt16 theRecordID, numInCategory; + MemHandle recordH; + MailDBRecordType record; + MailPackedDBRecordPtr src, dest; + Err err; + UInt16 attr; + + MessageOriginalRecordData = NULL; + + numInCategory = DmNumRecordsInCategory ( MailDB, ignoreCategory); + + + if (numInCategory == 0) + return; + +/* +{ +//debug +char tmp[32]; +StrIToA(tmp, (long)numInCategory); +FrmCustomAlert ( 2009, "RestoreRevert", "numInCategory" , tmp); +} +*/ + theRecordID = 0; + err = DmSeekRecordInCategory (MailDB, &theRecordID, 0, dmSeekForward, ignoreCategory); + if (err) + return; + + + if (!keepIt) + { + DmRemoveRecord (MailDB, theRecordID); + return; + } + + + //remove any revert data & return + //set the record back to the original category + DmRecordInfo (MailDB, theRecordID, &attr, NULL, NULL); + attr &= ~(dmRecAttrCategoryMask | dmRecAttrDirty); + attr |= MessageRevertCategory; + DmSetRecordInfo (MailDB, theRecordID, &attr, NULL); + + //if found, read it and delete it + MailGetRecord (MailDB, theRecordID, &record, &recordH); + + //make a copy of the record + MessageOriginalRecordData = MemHandleNew(MemHandleSize(recordH)); + MemHandleUnlock(recordH); + + //lock winDown both Handles + src = (MailPackedDBRecordPtr) MemHandleLock (recordH); + dest = (MailPackedDBRecordPtr) MemHandleLock (MessageOriginalRecordData); + + //copy the data into the new MemHandle + err = MemMove( dest, src, MemHandleSize(recordH)); + + //unlock the handles + MemHandleUnlock(recordH); + MemHandleUnlock(MessageOriginalRecordData); + + //remove the record + DmRemoveRecord (MailDB, theRecordID); + + CurrentCategory = MessageRevertCategory; + }//RestoreRevert + +/*********************************************************************** + * + * FUNCTION: SaveRevert + * + * DESCRIPTION: Store the revert MemHandle in the databasein the ignoreCategory, + * Mark it deleted (Archived), move it to the end of the database. + * + * PARAMETERS: none + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/14/97 Initial Revision + * grant 7/7/99 Free MessageOriginalRecordData handle once the data is + * added to the DB. + ***********************************************************************/ +static void SaveRevert() + { + Err err; + UInt16 attr; + UInt16 theNewRecord, numRecords; + MailPackedDBRecordPtr src; + MemHandle h; + MailDBRecordType record; + + if (!MessageOriginalRecordData) + return; + + h = MessageOriginalRecordData; + src = (MailPackedDBRecordPtr) MemHandleLock (h); + MailUnpackRecord (src, &record); + + // Add a new record into the database. + err = MailNewRecord (MailDB, &record, &theNewRecord); + if (err) + return; + MemHandleUnlock(h); + + // MessageOriginalRecordData has been added to DB, so release the memory + MemHandleFree(h); + MessageOriginalRecordData = NULL; + + // Put the new record in the ignore category. + DmRecordInfo (MailDB, theNewRecord, &attr, NULL, NULL); + attr &= ~(dmRecAttrCategoryMask | dmRecAttrDirty); + attr |= ignoreCategory; + DmSetRecordInfo (MailDB, theNewRecord, &attr, NULL); + + numRecords = DmNumRecords (MailDB); + //DmArchiveRecord (MailDB, theNewRecord); + DmMoveRecord (MailDB, theNewRecord, numRecords); + }//SaveRevert + +/*********************************************************************** + * + * FUNCTION: MessageViewCleanUpRevert + * + * DESCRIPTION: This routine removed the data stored by the revert code. + * + * PARAMETERS: nothing + * + * RETURNED: error code. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/14/97 Initial Revision + ***********************************************************************/ +static void MessageViewCleanUpRevert() + { + //if there was one already, free it + if (MessageOriginalRecordData) + { + MemHandleFree(MessageOriginalRecordData); + MessageOriginalRecordData = NULL; + } + }//MessageViewCleanUpRevert + +/*********************************************************************** + * + * FUNCTION: MessageViewDoCommand + * + * DESCRIPTION: This routine preforms the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/4/96 Initial Revision + * MGolden 7/7/97 Added the change font menu + * MGolden 7/21/97 Set the ReturnToView when the user selects NEW + * So we will come back to the mesage that they were editing + * when they are done with the new message. + * + ***********************************************************************/ +static void MessageViewDoCommand (UInt16 command) +{ + switch (command) + { + case messageNewMenuCmd: + if (CreateRecord ()) + { + //Set the ReturnToView when the user selects NEW + ReturnToView = MessageView; + FrmGotoForm (NewView); + } + break; + + case messageFileMenuCmd: + if (CurrentCategory != filedCategory) + { + if (MessageViewFileMessage()) + FrmGotoForm (ListView); + } + else + SndPlaySystemSound (sndError); + break; + + case messageCopyCmd: + MsgCopy (); + break; + + case messageSelectAllCmd: + MsgSelectAll (); + break; + + //mgmg added change font menu item + case messageChangeFontCmd: + MessageViewToggleFont (); + break; + + case messagePreferencesMenuCmd: + FrmPopupForm (PrefDialog); + break; + + case messageHotSyncMenuCmd: + FrmPopupForm (SyncDialog); + break; + + case messagePurgeMenuCmd: + if (PurgeDeletedRecord () && CurrentCategory == deletedCategory) + { + CurrentRecord = noRecordSelected; + ChangeCategory (deletedCategory); + FrmGotoForm (ListView); + } + break; + + case messageAboutMenuCmd: + AbtShowAbout (sysFileCMail); + break; + + } +} + + +/*********************************************************************** + * + * FUNCTION: MessageViewGoTo + * + * DESCRIPTION: This routine handles a frmGotoEvent + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/29/96 Initial Revision + * + ***********************************************************************/ +static void MessageViewGoTo (EventPtr event) +{ + MsgSelectFieldType selFld; + + MessageTopField = (MsgFieldType) event->data.frmGoto.matchFieldNum; + MessageScrollPos = event->data.frmGoto.matchPos; + + switch (MessageTopField) + { + case msgFieldSentTo: selFld = msgSelectSentTo; break; + case msgFieldTo: selFld = msgSelectTo; break; + case msgFieldFrom: selFld = msgSelectFrom; break; + case msgFieldSubject: selFld = msgSelectSubject; break; + case msgFieldCC: selFld = msgSelectCC; break; + case msgFieldDate: selFld = msgSelectDate; break; + case msgFieldBlankLine: selFld = msgSelectBlankLine; break; + case msgFieldBody: selFld = msgSelectBody; break; + } + + MessageSelectStartField = selFld; + MessageSelectEndField = selFld; + MessageSelectStartPos = event->data.frmGoto.matchPos; + MessageSelectEndPos = event->data.frmGoto.matchPos + + event->data.frmGoto.matchLen; +} + + +/*********************************************************************** + * + * FUNCTION: MessageViewClose + * + * DESCRIPTION: This routine initializes the Message View form. + * + * PARAMETERS: frm - pointer to the Message View form. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/4/96 Initial Revision + * + ***********************************************************************/ +static void MessageViewClose (void) +{ + // Release the block that holds the title. + if (MessageTitleH) + { + MemHandleFree (MessageTitleH); + MessageTitleH = NULL; + } +} + + +/*********************************************************************** + * + * FUNCTION: MessageViewInit + * + * DESCRIPTION: This routine initializes the Message View form. + * + * PARAMETERS: frm - pointer to the Message View form. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/4/96 Initial Revision + * MGolden 7/7/97 removed the font buttons + * MGolden 7/10/97 Added the undelete button to the deleted view + * Changed the ReturnToView for the deleted category. + * Otherwise, error occurs after an edit then send of + * Deleted (Created) mail. + * MGolden 7/21/97 Always set the return to view to the list view. It will be set + * To the message view if the user selects new from the message view. + * + ***********************************************************************/ +static void MessageViewInit (FormPtr frm) +{ + UInt16 controlID; + //MailDBRecordType record; + //MemHandle recordH; + + MessageViewSetTitle (); + + // Highlight the correct Header push button. + if (ShowFullHeader) + controlID = MessageFullHeaderButton; + else + controlID = MessageAbbrHeaderButton; + FrmSetControlGroupSelection (frm, MessageHeaderGroup, controlID); + + + // Highlight the corect font push button. + //mgmg removed the font buttons + + // If the outbox is being shown then hide the reply button, otherwise + // hide the unsend button. + MessageViewEnableButtons(frm); + + if (ShowFullHeader) + MessageTopField = msgFieldTo; + else + MessageTopField = msgFieldSentTo; + + MessageScrollPos = 0; + MessageSelectStartField = msgSelectNone; + MessageSelectEndField = msgSelectNone; + MessageSelectStartPos = 0; + MessageSelectEndPos = 0; + +#ifdef NEEDED + // Set the following global so that we will return to the Message + // View when a new message is sent. + if (CurrentCategory == outboxCategory || CurrentCategory == draftCategory || +//mgmg new??? +//ROGER? + CurrentCategory == deletedCategory || CurrentCategory == filedCategory ) + ReturnToView = ListView; + else + ReturnToView = MessageView; +#endif + + //always return to the list view! + ReturnToView = ListView; +} + +/*********************************************************************** + * + * FUNCTION: MessageViewEnableButtons + * + * DESCRIPTION: Show & hide the buttons in the message view, based on the current + * Category & message. The form may already be open, so we can not + * assume what buttons are already visible. + * + * PARAMETERS: the formPtr + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/10/97 Initial Revision + * Mgolden 9/29/97 added code to hide the next & prev buttons if + * there is only one message in the category. + * + ***********************************************************************/ +static void MessageViewEnableButtons(FormPtr frm) + { + MemHandle recordH; + MailDBRecordType record; + Boolean read = false; + + //how many messages are there...show or hide the next & prev buttons + if (DmNumRecordsInCategory (MailDB, CurrentCategory) == 1) + { + FrmHideObject (frm, FrmGetObjectIndex (frm, MessagePrevMessageButton)); + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageNextMessageButton)); + } + else + { + FrmShowObject (frm, FrmGetObjectIndex (frm, MessagePrevMessageButton)); + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageNextMessageButton)); + } + + if (CurrentCategory == inboxCategory) + { + //hide edit & undelete + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageEditButton)); + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageUndeleteButton)); + + //show reply & delete + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageReplyButton)); + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageDeleteButton)); + return; + } + + if (CurrentCategory == outboxCategory || CurrentCategory == draftCategory) + { + //hide reply & undelete + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageReplyButton)); + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageUndeleteButton)); + + //show edit & delete + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageEditButton)); + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageDeleteButton)); + return; + } + + //read the record and find out if it is a read message, or a created one + MailGetRecord (MailDB, CurrentRecord, &record, &recordH); + //if ((!record.flags.read) && (!record.from || (record.from[0] == '\0'))) + if ((!record.from || (record.from[0] == '\0'))) + read = false; + else + read = true; + //unlock the record + MemHandleUnlock (recordH); + + if (CurrentCategory == deletedCategory) + { + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageDeleteButton)); + + if (read) + { + //hide edit + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageEditButton)); + + //show reply & undelete + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageReplyButton)); + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageUndeleteButton)); + } + else + { + //hide reply, & undelete + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageReplyButton)); + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageUndeleteButton)); + + //show edit + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageEditButton)); + } + return; + } + + if (CurrentCategory == filedCategory) + { + if (read) + { + //hide edit & undelete + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageEditButton)); + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageUndeleteButton)); + + //show reply & delete + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageReplyButton)); + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageDeleteButton)); + } + else + { + //hide reply, & undelete + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageReplyButton)); + FrmHideObject (frm, FrmGetObjectIndex (frm, MessageUndeleteButton)); + + //show edit & delete + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageEditButton)); + FrmShowObject (frm, FrmGetObjectIndex (frm, MessageDeleteButton)); + } + return; + } + + }//MessageViewEnableButtons + + +/*********************************************************************** + * + * FUNCTION: MessageViewHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "Message View". + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has handled and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/4/96 Initial Revision + * MGolden 7/7/97 removed the font buttons + * MGolden 7/10/97 added code for the Undelete button. + * kwk 11/22/98 MemHandle command keys in separate code block so that + * TxtCharIsPrint doesn't get called w/virtual chars. + * jmp 10/29/99 Handle frmUpdateEvent ourselves now so we don't + * have partially drawn screens. + * jmp 10/31/99 Factored out commonality among frmOpenEvent, frmUpdateEvent, and + * frmGotoEvent since they are all substantially the same. + * + ***********************************************************************/ +static Boolean MessageViewHandleEvent (EventPtr event) +{ + UInt16 objIndex; + FormPtr frm; + RectangleType r; + Boolean handled = false; + + if (event->eType == keyDownEvent) + { + // Mail key pressed? If so display the next mail message. + if (TxtCharIsHardKey(event->data.keyDown.modifiers, event->data.keyDown.chr)) + { + if (! (event->data.keyDown.modifiers & poweredOnKeyMask)) + { + if (! MessageViewNextMessage (dmSeekForward)) + FrmGotoForm (ListView); + handled = true; + } + } + + else if (EvtKeydownIsVirtual(event)) + { + if (event->data.keyDown.chr == vchrPageUp) + { + MessageViewPageScroll (winUp); + handled = true; + } + + else if (event->data.keyDown.chr == vchrPageDown) + { + MessageViewPageScroll (winDown); + handled = true; + } + } + } + + else if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case MessageDoneButton: + FrmGotoForm (ListView); + handled = true; + break; + + case MessageDeleteButton: + if (MessageViewDeleteMessage()) + FrmGotoForm (ListView); + handled = true; + break; + + case MessageReplyButton: + //mgmg return to the message after the reply! + ReturnToView = MessageView; + FrmPopupForm (ReplyDialog); + handled = true; + break; + + case MessageEditButton: + if (MessageViewUnsendMessage ()) + FrmGotoForm (NewView); + break; + + case MessageUndeleteButton: + if (MessageUndelete()) + { + //change the category to the inBox, we are going to follow this message there + ChangeCategory (inboxCategory); + FrmGotoForm (ListView); + } + break; + + case MessageAbbrHeaderButton: + case MessageFullHeaderButton: + MessageViewChangeHeader (event->data.ctlSelect.controlID); + handled = true; + break; + +//mgmg new 9/9/97 + case MessagePrevMessageButton: + MessageViewNextMessage (dmSeekBackward); + handled = true; + break; + + case MessageNextMessageButton: + MessageViewNextMessage (dmSeekForward); + handled = true; + break; + } + } + + else if (event->eType == penDownEvent) + { + frm = FrmGetActiveForm (); + objIndex = FrmGetObjectIndex (frm, MessageGadget); + FrmGetObjectBounds (frm, objIndex, &r); + if (RctPtInRectangle (event->screenX, event->screenY, &r)) + MsgSelect (event->screenX, event->screenY); + } + + else if (event->eType == menuEvent) + { + MessageViewDoCommand (event->data.menu.itemID); + return (true); + } + + else if (event->eType == menuCmdBarOpenEvent) + { + MenuCmdBarAddButton(menuCmdBarOnRight, BarCopyBitmap, menuCmdBarResultMenuItem, messageCopyCmd, 0); + + // tell the field package to not add cut/copy/paste buttons automatically + event->data.menuCmdBarOpen.preventFieldButtons = true; + + handled = false; // mustn't say it is handled, otherwise the OS won't bring up the bar. + } + + else if (event->eType == sclRepeatEvent) + { + MessageViewScroll (event->data.sclRepeat.newValue - + event->data.sclRepeat.value); + } + + else if (event->eType == frmOpenEvent || event->eType == frmUpdateEvent || event->eType == frmGotoEvent) + { + frm = FrmGetActiveForm (); + if (event->eType == frmGotoEvent) + CurrentRecord = event->data.frmGoto.recordNum; + if (event->eType == frmOpenEvent || event->eType == frmGotoEvent) + MessageViewInit (frm); + if (event->eType == frmGotoEvent) + MessageViewGoTo (event); + MessageViewUpdateScrollBar (); + FrmDrawForm (frm); + MsgDraw (); + MessageViewMarkRead (); + handled = true; + } + + else if (event->eType == frmCloseEvent) + { + MessageViewClose (); + } + + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewSetTitle + * + * DESCRIPTION: This routine formats and sets the title of the List View. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 06/12/96 Initial Revision + * MGolden 7/7/97 changed format to "x Unread, y Total". + * Also changed it from the title to a label object next to the title + * # = UnreadMessages, % = MessagesInCategory + * MGolden 7/9/97 Inbox works as above, all others use "# Total" instead + * kwk 05/28/99 Use const Char* for label text. + * kwk 06/28/99 Fixed calls to FrmHide/ShowObject using object id vs. index. + * + ***********************************************************************/ +static void ListViewSetTitle (void) +{ + UInt16 len; + Char countStr [6]; + Char * titleTemplateP; + Char * tmp; + Char * title; + Char * MemPtr; + FormPtr frm; + Int16 total; + UInt16 objIndex; + + //check the count of records in the inBox + total = DmNumRecordsInCategory (MailDB, inboxCategory); + + if (CurrentCategory == inboxCategory && total > 0) + { + // Format the title string. A string resource is used as a template, the + // '#' character in the template indicates the postions of the numeric + // value. + // DOLATER kwk - use new IntlGlue call to create text MemPtr from template + // plus parameters. + + total = DmNumRecordsInCategory (MailDB, inboxCategory); + + if (total > 999) + titleTemplateP = MemHandleLock (DmGetResource (strRsc, listTitleShortStrID)); + else if (total == 1) + titleTemplateP = MemHandleLock (DmGetResource (strRsc, listTitleSingularStringId)); + else + titleTemplateP = MemHandleLock (DmGetResource (strRsc, listTitleStringId)); + + StrIToA (countStr, UnreadMessages); + len = StrLen (countStr) + StrLen (titleTemplateP); + + tmp = MemPtrNew (len + 1); + ErrFatalDisplayIf (!tmp, "Out of memory"); + + MemPtr = StrChr (titleTemplateP, '#'); + len = MemPtr - titleTemplateP; + if (len) + StrNCopy (tmp, titleTemplateP, len); + tmp[len] = 0; + StrCat (tmp, countStr); + MemPtr++; + StrCat (tmp, MemPtr); + + //now title has the unread count...add the total count of the inbox category + //total = DmNumRecordsInCategory (MailDB, inboxCategory); + StrIToA (countStr, total); + len = StrLen (countStr) + StrLen (tmp); + + title = MemPtrNew (len + 1); + ErrFatalDisplayIf (!title, "Out of memory"); + + MemPtr = StrChr (tmp, '%'); + len = MemPtr - tmp; + if (len) + StrNCopy (title, tmp, len); + title[len] = 0; + StrCat (title, countStr); + MemPtr++; + StrCat (title, MemPtr); + + //free the tmp MemPtr + MemPtrFree(tmp); + } + else + { + // Format the title string. A string resource is used as a template, the + // '#' character in the template indicates the postions of the numeric + // value. + total = DmNumRecordsInCategory (MailDB, CurrentCategory); + + if (total == 1) + titleTemplateP = MemHandleLock (DmGetResource (strRsc, listTitleNotInboxSingularStrId)); + else + titleTemplateP = MemHandleLock (DmGetResource (strRsc, listTitleNotInboxStringId)); + + StrIToA (countStr, total); + len = StrLen (countStr) + StrLen (titleTemplateP); + + title = MemPtrNew (len + 1); + ErrFatalDisplayIf (!title, "Out of memory"); + + MemPtr = StrChr (titleTemplateP, '#'); + len = MemPtr - titleTemplateP; + StrNCopy (title, titleTemplateP, len); + title[len] = 0; + StrCat (title, countStr); + + MemPtr++; + StrCat (title, MemPtr); + } + + //erase the title area then re-draw it + frm = FrmGetFormPtr (ListView); + + objIndex = FrmGetObjectIndex (frm, ListTitleLabel); + FrmHideObject (frm, objIndex); + FrmCopyLabel (frm, ListTitleLabel, title); + FrmShowObject (frm, objIndex); + + MemPtrUnlock(titleTemplateP); + MemPtrFree(title); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewDrawDate + * + * DESCRIPTION: This routine draws a messages date. + * + * PARAMETERS: table - pointer to a table object + * row - row the item is in + * column - column the item is in + * bounds - region to draw in + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/3/96 Initial Revision + * + ***********************************************************************/ +static void ListViewDrawDate (DateType date, Int16 x, Int16 y) +{ + UInt16 dateStrLen; + Char dateBuffer [dateStringLength]; + Int16 drawX, drawY; + Char * dateStr; + FontID currFont; + + currFont = FntSetFont (ListFont); + + // If there is no date draw a dash to indicate such. + if (DateToInt (date) == noDate) + { + drawX = x + ((listDateWidth - 5) >> 1); + drawY = y + ((FntLineHeight () + 1) / 2); + WinDrawLine (drawX, drawY, drawX+5, drawY); + } + + else + { + DateToAscii (date.month, date.day, date.year + firstYear, + DateFormat, dateBuffer); + + // Remove the year from the date string. + dateStr = dateBuffer; + if ((DateFormat == dfYMDWithSlashes) || + (DateFormat == dfYMDWithDots) || + (DateFormat == dfYMDWithDashes)) + dateStr += 3; + else + { + dateStr[StrLen(dateStr) - 3] = 0; + } + + + // Draw the due date, right aligned. + dateStrLen = StrLen (dateStr); + WinDrawChars (dateStr, + dateStrLen, + x + listDateWidth - FntCharsWidth (dateStr, dateStrLen), + y); + } + + FntSetFont (currFont); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewDrawRecord + * + * DESCRIPTION: This routine the draw the title memo record in the list + * view. This routine is called by the table routine, + * TblDrawTable, each time a line of the table needs to + * be drawn. + * + * PARAMETERS: table - pointer to the memo list table (TablePtr) + * row - row of the table to draw + * column - column of the table to draw + * bounds - bound to the draw region + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/31/96 Initial Revision + * MGolden 7/9/97 Draw the missing subject text (noSubjectListViewStrID) + * if there is no subject to draw. Also draw the Missing + * To: text if there is no To: + * MGolden 7/9/97 Set drawing order back to: To, Subject, Date + * MGolden 7/9/97 Removed code to strip the to/from field at a space or @ + * + ***********************************************************************/ +static void ListViewDrawRecord (void * table, Int16 row, Int16 UNUSED_PARAM(column), + RectanglePtr bounds) +{ + //Char ch; + Char name [maxListFromNameLen]; + Int16 x, y, offset; + Int16 width; + UInt16 recordNum; + MemHandle recordH; + Boolean showDateColumn; + MailDBRecordType record; +// Char * atSymbolP; +// Char * lastSpaceP; + Int16 subjectWidth; + Int16 addressWidth; + Char * subject; + Char title[32]; + FontID curFont; + UInt16 iconID = 0; + MemHandle h; + BitmapPtr bitmapP; + + // Get the record number that corresponds to the table item to draw. + // The record number is stored in the "intValue" field of the item. + recordNum = TblGetRowID (table, row); + MailGetRecord (MailDB, recordNum, &record, &recordH); + + x = bounds->topLeft.x; + y = bounds->topLeft.y; + width = bounds->extent.x; + + // Draw the check mark icon. + if (CurrentCategory == inboxCategory) + { + iconID = 0; + if (record.flags.read) + { + if (record.flags.priority == priorityHigh) + iconID = readUrgentIconID; + else + iconID = readIconID; + } + else if (record.flags.priority == priorityHigh) + iconID = urgentIconID; + + if (iconID > 0) + { + //draw the icon + h = DmGetResource ('Tbmp', iconID); + if (h) + { + bitmapP = (BitmapPtr)MemHandleLock(h); + if (bitmapP) + { + //center the icon vertically in the space + if ((*bitmapP).height < bounds->extent.y) + offset = (bounds->extent.y - (*bitmapP).height)/2; + else + offset = 0; + + WinDrawBitmap (bitmapP , bounds->topLeft.x, bounds->topLeft.y + offset); + MemPtrUnlock (bitmapP); + } + DmReleaseResource (h); + } + } + x += listIconWidth; + width -= listIconWidth; + } + + + +#ifdef OLDWAY + if (CurrentCategory == inboxCategory) + { +//draw the check centered in the line height + + FntSetFont (symbolFont); + ch = symbolCheckMark; + if (record.flags.read) + WinDrawChars (&ch, 1, x, y); + x += FntCharWidth (ch) + 2; + width -= x; + + listIconWidth + + } +#endif + + showDateColumn = ShowDates && + CurrentCategory != outboxCategory && + CurrentCategory != draftCategory; + + if (showDateColumn) + width -= listDateWidth + listColumnSpacing; + + width -= listColumnSpacing; + +// addressWidth = width / 3; + addressWidth = width / 2; + subjectWidth = width - addressWidth; + +/* + if (record.flags.priority == priorityHigh) + curFont = FntSetFont (boldFont); + else + curFont = FntSetFont (stdFont); +*/ + curFont = FntSetFont (ListFont); + + // Draw the address. If the current category is the outbox then + // draw the "to" field, otherwise draw the "from" field. + if (CurrentCategory != outboxCategory && CurrentCategory != draftCategory) + { + if (*record.from) + { + // Get the friendly name if there is one. + MailParseAddress (record.from, true, name, sizeof (name)); + +/* + // Because the name column is only a third of the width + // show only the most important part of the sender's name + + // Strip off the domain name + atSymbolP = StrChr(name, '@'); + if (atSymbolP) + { + *atSymbolP = '\0'; + } + else + { + // Strip off the last name. The last name is stripped instead of + // of the first name because users probably get mail from people with + // the same last name (family members) than the same first names. + lastSpaceP = StrChr(name, ' '); + if (lastSpaceP) + { + *lastSpaceP = '\0'; + } + } +*/ + DrawString (name, x, y, addressWidth); + } + // check the to field ... + else if (*record.to) + { + //is there a to? + MailParseAddress (record.to, true, name, sizeof (name)); + DrawString (name, x, y, addressWidth); + } + else + { + //draw the missing string? + subject = MemHandleLock (DmGetResource (strRsc, noToListViewStrID)); + StrCopy (title, subject); + MemPtrUnlock (subject); + DrawString (title, x, y, addressWidth); + } + } + else + { + if (*record.to) + { + //mgmg changed 8/4/97 + //DrawString (record.to, x, y, addressWidth); + MailParseAddress (record.to, true, name, sizeof (name)); + DrawString (name, x, y, addressWidth); + } + else + { + //there is no To Field, draw the missing to field message + subject = MemHandleLock (DmGetResource (strRsc, noToListViewStrID)); + StrCopy (title, subject); + MemPtrUnlock (subject); + DrawString (title, x, y, addressWidth); + } + } + x += addressWidth; + + // Draw a line between the address and subject columns. + WinDrawLine (x + 1, y, x + 1, y + bounds->extent.y - 1); + x += listColumnSpacing; + + // Draw the "subject" field. + if (*record.subject) + DrawString (record.subject, x, y, subjectWidth); +//mgmg : draw the noSubjectListViewStrID if there is no subject + else + { + subject = MemHandleLock (DmGetResource (strRsc, noSubjectListViewStrID)); + StrCopy (title, subject); + MemPtrUnlock (subject); + DrawString (title, x, y, subjectWidth); + } + + + x += subjectWidth; + + if (showDateColumn) + { + // Draw a line between the subject and date columns. + WinDrawLine (x + 1, y, x + 1, y + bounds->extent.y - 1); + x += listColumnSpacing; + + + // Draw the "date" field. + FntSetFont (stdFont); + ListViewDrawDate (record.date, x, y); + } + + MemHandleUnlock (recordH); + + FntSetFont (curFont); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewUpdateScrollers + * + * DESCRIPTION: This routine draws or erases the list view scroll arrow + * buttons. + * + * PARAMETERS: frm - pointer to the to do list form + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/3/96 Initial Revision + * + ***********************************************************************/ +static void ListViewUpdateScrollers (TablePtr table) +{ + Int16 rows; + UInt16 width; + UInt16 minValue; + UInt16 maxValue; + RectangleType r; + + ErrNonFatalDisplayIf (DmNumRecordsInCategory (MailDB, CurrentCategory) != + MessagesInCategory, "Invalid record count"); + + //rows = TblGetNumberOfRows (table); + rows = ListViewNumberOfRows (GetObjectPtr(ListTable)); + + // Leave room for the scroll bar if it will be visible. + FrmGetFormBounds (FrmGetActiveForm (), &r); + width = r.extent.x; + if (MessagesInCategory > rows) + width -= listScrollBarWidth; + + TblSetColumnWidth (table, 0, width); + TblGetBounds (table, &r); + r.extent.x = width; + TblSetBounds (table, &r); + + + if (MessagesInCategory) + minValue = DmPositionInCategory (MailDB, TopVisibleRecord, CurrentCategory); + else + minValue = 0; + + if (MessagesInCategory > rows) + maxValue = MessagesInCategory - rows; + else + maxValue = 0; + + SclSetScrollBar (GetObjectPtr (ListScrollBar), minValue, 0, maxValue, rows); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewLoadTable + * + * DESCRIPTION: This routine loads memo database records into + * the list view form. + * + * PARAMETERS: recordNum index of the first record to display. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/31/96 Initial Revision + * + ***********************************************************************/ +static void ListViewLoadTable (FormPtr frm, UInt16 recordNum) +{ + UInt16 row; + UInt16 lastRecordNum; + UInt16 numRows; + UInt32 uniqueID; + TablePtr table; + MemHandle recordH; + FontID currFont; + RectangleType r; + UInt16 dataHeight; + UInt16 tableHeight; + UInt16 lineHeight; + + + table = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, ListTable)); + + /* HandEra */ + if (vgaExists) + VgaTableUseBaseFont(table, !VgaIsVgaFont(ListFont)); + /* end HandEra */ + + TblGetBounds (table, &r); + tableHeight = r.extent.y; + + dataHeight = 0; + + currFont = FntSetFont (ListFont); + lineHeight = FntLineHeight (); + FntSetFont (currFont); + + // For each row in the table, store the record number in the table item + // that will dispaly the record. + numRows = TblGetNumberOfRows (table); + for (row = 0; row < numRows; row++) + { + // Get the next record in the currunt category. + recordH = DmQueryNextInCategory (MailDB, &recordNum, + CurrentCategory); + + // If the record was found, store the record number in the table item, + // otherwise set the table row unusable. +// if (recordH) + if (recordH && (tableHeight >= dataHeight + lineHeight)) + { + TblSetRowID (table, row, recordNum); + +//new font stuff + TblSetItemStyle (table, row, 0, customTableItem); + TblSetItemFont (table, row, 0, ListFont); + TblSetRowHeight (table, row, lineHeight); + + DmRecordInfo (MailDB, recordNum, NULL, &uniqueID, NULL); + if (TblGetRowData (table, row) != uniqueID || + (!TblRowUsable (table, row))) + { + TblSetRowUsable (table, row, true); + + // Store the unique id of the record in the row. + TblSetRowData (table, row, uniqueID); + + // Mark the row invalid so that it will draw when we call the + // draw routine. + TblMarkRowInvalid (table, row); + } + + lastRecordNum = recordNum; + if (row+1 < numRows) + recordNum++; + + dataHeight += lineHeight; + } + else + { + TblSetRowUsable (table, row, false); + TblSetItemFont (table, row, 0, ListFont); + TblSetRowHeight (table, row, lineHeight); + } + } + + // Update the scroll arrows. + ListViewUpdateScrollers (table); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewLoadRecords + * + * DESCRIPTION: This routine loads memo database records into + * the list view form. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/30/96 Initial Revision + * + ***********************************************************************/ +static void ListViewLoadRecords (FormPtr frm) +{ + TablePtr table; + UInt16 recordNum; + UInt16 rowsInTable; + + table = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, ListTable)); + //rowsInTable = TblGetNumberOfRows (table); + rowsInTable = ListViewNumberOfRows (table); + + + // Is the current record before the first visible record? + if (CurrentRecord != noRecordSelected) + { + if (TopVisibleRecord > CurrentRecord) + TopVisibleRecord = CurrentRecord; + + // Is the current record after the last visible record? + else + { + recordNum = TopVisibleRecord; + DmSeekRecordInCategory (MailDB, &recordNum, rowsInTable-1, + dmSeekForward, CurrentCategory); + if (recordNum < CurrentRecord) + TopVisibleRecord = CurrentRecord; + } + } + + + // Make sure we show a full display of records. + recordNum = dmMaxRecordIndex; + if (DmSeekRecordInCategory (MailDB, &recordNum, (rowsInTable-1), + dmSeekBackward, CurrentCategory) == 0) + TopVisibleRecord = min (TopVisibleRecord, recordNum); + else + TopVisibleRecord = 0; + + ListViewLoadTable (frm, TopVisibleRecord); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewChangeCategory + * + * DESCRIPTION: This routine display the category specified + * + * PARAMETERS: category - new category + * + * RETURNED: The index of the new category. + * + * The following global variables are modified: + * CurrentCategory + * ShowAllCategories + * CategoryName + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/3/96 Initial Revision + * + ***********************************************************************/ +static void ListViewChangeCategory (UInt16 category) +{ + FormPtr frm; + TablePtr table; + + frm = FrmGetActiveForm (); + table = GetObjectPtr (ListTable); + + ChangeCategory (category); + + // Display the new category. + TblEraseTable (table); + + ListViewLoadTable (frm, TopVisibleRecord); + + TblDrawTable (table); + + ListViewSetTitle (); + + //unset the current record..it will not be in the new category! + CurrentRecord = noRecordSelected; + + //mgmg 7/16 + //ListViewSelectRecord(frm, CurrentRecord, true); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewUpdateDisplay + * + * DESCRIPTION: This routine updates the display of the List View + * + * PARAMETERS: updateCode - a code that indicated what changes have been + * made to the to do list. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/3/96 Initial Revision + * MGolden 10/3/97 Rocky font changes + * jmp 10/31/99 Handle frmRedrawUpdateCode as the generic form + * handling code no longer works for us in Palm + * OS 3.5 and later. + * + ***********************************************************************/ +static Boolean ListViewUpdateDisplay (UInt16 updateCode) +{ + TablePtr table; + + table = GetObjectPtr (ListTable); + + // Was the UI unable to save an image of the ListView when it + // obscured part of the view with another dialog? If so we'll + // handle it here. + if (updateCode & frmRedrawUpdateCode) + { + FormPtr frm = FrmGetActiveForm (); + FrmDrawForm (frm); + ListViewSelectRecord (frm, CurrentRecord, true); + return (true); + } + + // Were the display options modified (ToDoOption dialog)? + if (updateCode & (updateDisplayOptsChanged | updateFontChanged)) + { + //new for rocky font + TopVisibleRecord = 0; + + ListViewLoadRecords (FrmGetActiveForm()); + table = GetObjectPtr (ListTable); + TblEraseTable (table); + TblDrawTable (table); + + //TblEraseTable (table); + //ListViewLoadTable (FrmGetActiveForm (), TopVisibleRecord); + //TblDrawTable (table); + //mgmg + //ListViewSelectRecord(FrmGetActiveForm (), CurrentRecord, true); + return (true); + } + + // Were deleted records purged? + if (updateCode & updatePurge) + { + SeekRecord (&TopVisibleRecord, 0, dmSeekForward); + ListViewLoadTable (FrmGetActiveForm (), TopVisibleRecord); + TblRedrawTable(table); + return (true); + } + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewScroll + * + * DESCRIPTION: This routine scrolls the list of of message + * in the direction specified. + * + * PARAMETERS: direction - winUp or dowm + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/3/96 Initial Revision + * MGolden 7/16/97 De-select the current selction before scrolling + * because of a bug in the table code that will trash the table struct + * if the selected item is not a valid row. + * + * TABLE does not MemHandle font's correctly! + * + ***********************************************************************/ +static void ListViewScroll (Int16 linesToScroll) +{ + Int16 i; + UInt16 rows; + UInt16 lastRow; + UInt16 scrollAmount; + UInt16 lastRecord; + UInt16 newTopVisibleRecord; + TablePtr table; + RectangleType scrollR; + RectangleType vacated; + WinDirectionType direction; + + //CurrentRecord = noRecordSelected; + + table = GetObjectPtr (ListTable); + //rows = TblGetNumberOfRows (table); + rows = ListViewNumberOfRows (table); + + //de-select the table item... + TblUnhighlightSelection (table); + + // Find the new top visible record + newTopVisibleRecord = TopVisibleRecord; + + // Scroll winDown. + if (linesToScroll > 0) + { + if (! SeekRecord (&newTopVisibleRecord, linesToScroll, dmSeekForward)) + return; + + lastRecord = TopVisibleRecord; + if (!SeekRecord (&lastRecord, rows, dmSeekForward)) + return; + + } + + // Scroll winUp. + else if (linesToScroll < 0) + { + if (! SeekRecord (&newTopVisibleRecord, -linesToScroll, dmSeekBackward)) + return; + } + + + TopVisibleRecord = newTopVisibleRecord; + + // Move the bits that will remain visible. + if (((linesToScroll > 0) && (linesToScroll < rows)) || + ((linesToScroll < 0) && (-linesToScroll < rows))) + { + scrollAmount = 0; + + if (linesToScroll > 0) + { + lastRow = TblGetLastUsableRow (table) - 1; + for (i = 0; i < linesToScroll; i++) + { + scrollAmount += TblGetRowHeight (table, lastRow); + TblRemoveRow (table, 0); + } + direction = winUp; + } + else + { + for (i = 0; i < -linesToScroll; i++) + { + scrollAmount += TblGetRowHeight (table, 0); + TblInsertRow (table, 0); + } + direction = winDown; + } + + TblGetBounds (table, &scrollR); + WinScrollRectangle (&scrollR, direction, scrollAmount, &vacated); + WinEraseRectangle (&vacated, 0); + } + + + ListViewLoadTable (FrmGetActiveForm (), TopVisibleRecord); + + TblRedrawTable(table); + + //mgmg 7/16 + //re-select the current record (only if it's visible now) + ListViewSelectRecord (FrmGetActiveForm (), CurrentRecord, false); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewPageScroll + * + * DESCRIPTION: This routine scrolls the list of of expense items + * in the direction specified. + * + * PARAMETERS: direction - winUp or dowm + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 1/2/96 Initial Revision + * + ***********************************************************************/ +static void ListViewPageScroll (WinDirectionType direction) +{ + TablePtr table; + Int16 row; + UInt16 recordNum; + Int16 rowsInTable; + UInt16 newTopVisibleRecord; + + table = GetObjectPtr (ListTable); + //rowsInTable = TblGetNumberOfRows (table); + rowsInTable = ListViewNumberOfRows (table); + + newTopVisibleRecord = TopVisibleRecord; + + //mgmg no reason for this that I can see... + //CurrentRecord = noRecordSelected; + + //de-select the table item... + TblUnhighlightSelection (table); + + // Scroll the table winDown a page (less one row). + if (direction == winDown) + { + // Get the record index of the last visible record. A row + // number of minus one indicates that there are no visible rows. + row = TblGetLastUsableRow (table); + if (row == -1) return; + + newTopVisibleRecord = TblGetRowID (table, row); + recordNum = newTopVisibleRecord; + + // Try going forward one page + if (!SeekRecord (&recordNum, rowsInTable - 1, dmSeekForward)) + { + // Try going backwards one page from the last record + newTopVisibleRecord = dmMaxRecordIndex; + if (!SeekRecord (&newTopVisibleRecord, rowsInTable - 1, dmSeekBackward)) + { + // Not enough records to fill one page. Start with the first record + newTopVisibleRecord = 0; + SeekRecord (&newTopVisibleRecord, 0, dmSeekForward); + } + } + } + + // Scroll winUp a page (less one row). + else + { + if (!SeekRecord (&newTopVisibleRecord, rowsInTable - 1, dmSeekBackward)) + { + // Not enough records to fill one page. Start with the first record + newTopVisibleRecord = 0; + SeekRecord (&newTopVisibleRecord, 0, dmSeekForward); + } + } + + // Avoid redraw if no change + if (TopVisibleRecord != newTopVisibleRecord) + { + TopVisibleRecord = newTopVisibleRecord; + +//mgmg do later +// ListViewLoadRecords (FrmGetActiveForm ()); +// TblRedrawTable(table); + + TblMarkTableInvalid (table); + ListViewLoadTable (FrmGetActiveForm (), TopVisibleRecord); + TblRedrawTable (table); + + } + //mgmg 8/4 + //re-select the current record (only if it's visible now) + ListViewSelectRecord (FrmGetActiveForm (), CurrentRecord, false); +} + + +/*********************************************************************** + * + * FUNCTION: ListViewDoCommand + * + * DESCRIPTION: This routine preforms the menu command specified. + * + * PARAMETERS: command - menu item id + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/4/96 Initial Revision + * + ***********************************************************************/ +static void ListViewDoCommand (UInt16 command) +{ + switch (command) + { + case newMenuCmd: + if (CreateRecord ()) + FrmGotoForm (NewView); + break; + +// case showMenuCmd: +// FrmPopupForm (OptionsDialog); +// break; + + case preferencesMenuCmd: + FrmPopupForm (PrefDialog); + break; + + case hotSyncMenuCmd: + FrmPopupForm (SyncDialog); + break; + + case purgeMenuCmd: + if (PurgeDeletedRecord ()) + { + // If the "deleted" catagory is shown, erease the table. + if (CurrentCategory == deletedCategory) + ListViewChangeCategory (deletedCategory); + else + FrmUpdateForm (ListView, updatePurge); + } + break; + + case aboutMenuCmd: + AbtShowAbout (sysFileCMail); + break; + + case ListChangeFontMenuCmd: + ListFont = SelectFont (ListFont); + break; + } +} + + +/* HandEra */ +/*********************************************************************** + * + * FUNCTION: ListViewResize + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + ***********************************************************************/ +static void ListViewResize(Boolean draw) +{ + FormPtr frmP; + Coord x, y; + Coord xDiff, yDiff; + TablePtr table; + RectangleType r; + + WinGetDisplayExtent(&x, &y); + + // this will get the old extent + // resize form + frmP = FrmGetActiveForm(); + FrmGetFormBounds(frmP, &r); + + xDiff = x - (r.topLeft.x + r.extent.x); + yDiff = y - (r.topLeft.y + r.extent.y); + if ((xDiff == 0) && (yDiff == 0)) + return; + + // resize form + r.extent.x += xDiff; + r.extent.y += yDiff; + WinSetWindowBounds(FrmGetWindowHandle(frmP), &r); + + // resize table + table = GetObjectPtr(ListTable); + TblGetBounds(table, &r); + r.extent.x += xDiff; + r.extent.y += yDiff; + TblSetBounds(table, &r); + + if(draw && (yDiff < 0)) + { + r.topLeft.y = (r.topLeft.y + r.extent.y); + r.extent.y = -yDiff; + WinEraseRectangle (&r, 0); + } + + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, ListNewButton), 0, yDiff, draw); + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, ListShowButton), 0, yDiff, draw); + + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, ListScrollBar), xDiff, 0, false); + ToolsResizeObject(frmP, FrmGetObjectIndex(frmP, ListScrollBar), 0, yDiff, draw); + + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, ListCategoryTrigger), xDiff, 0, draw); + ToolsMoveObject(frmP, FrmGetObjectIndex(frmP, ListCategoryList), xDiff, 0, draw); + + if (draw) + { + ListViewLoadTable(frmP, TopVisibleRecord); + FrmDrawForm(frmP); + } +} +/* end HandEra */ + +/*********************************************************************** + * + * FUNCTION: ListViewInit + * + * DESCRIPTION: This routine initializes the "List View" of the + * Mail application. + * + * PARAMETERS: event - a pointer to an EventType structure + * + * RETURNED: true if the event has MemHandle and should not be passed + * to a higher level handler. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/31/96 Initial Revision + * + ***********************************************************************/ +static void ListViewInit (FormPtr frm) +{ + Int16 row; + Int16 rowsInTable; + ListPtr lst; + TablePtr table; + ControlPtr ctl; + + ListViewResize(false); + + MessagesInCategory = DmNumRecordsInCategory (MailDB, CurrentCategory); + + ListViewSetTitle (); + + // Set the label of the category trigger. + ctl = GetObjectPtr (ListCategoryTrigger); + CategoryGetName (MailDB, CurrentCategory, CategoryName); + CategorySetTriggerLabel (ctl, CategoryName); + + // Set the category list selection. + lst = GetObjectPtr (ListCategoryList); + LstSetSelection (lst, CurrentCategory); + + //now get the current table + table = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, ListTable)); + + rowsInTable = TblGetNumberOfRows (table); + for (row = 0; row < rowsInTable; row++) + { + TblSetItemStyle (table, row, 0, customTableItem); + TblSetRowUsable (table, row, false); + } + + // Set the callback routine that will draw the records. + TblSetCustomDrawProcedure (table, 0, ListViewDrawRecord); + + TblSetColumnUsable (table, 0, true); + + ListViewLoadRecords (frm); + + // Set the following global so that we will return to the List + // View when a new message is sent. + ReturnToView = ListView; +} + + +/*********************************************************************** + * + * FUNCTION: ListViewHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "List View" + * of the Mail 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. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 05/31/96 Initial Revision + * kwk 11/22/98 MemHandle command keys in separate code block so that + * TxtCharIsPrint doesn't get called w/virtual chars. + * jmp 10/31/99 Perform FrmDrawForm() in frmOpenForm BEFORE calling + * ListViewSelectRecord() to prevent selected record from + * getting drawn as unselected. Fixes bug #23416. + * + ***********************************************************************/ +static Boolean ListViewHandleEvent (EventPtr event) +{ + FormPtr frm; + TablePtr table; + Boolean handled = false; + + if (event->eType == keyDownEvent) + { + // Mail key pressed? If so display the first mail message. + if (TxtCharIsHardKey(event->data.keyDown.modifiers, event->data.keyDown.chr)) + { + if (! (event->data.keyDown.modifiers & poweredOnKeyMask)) + { + table = GetObjectPtr (ListTable); + if (TblRowUsable (table, 0)) + { + CurrentRecord = TblGetRowID (table, 0); + FrmGotoForm (MessageView); + } + handled = true; + } + } + + else if (EvtKeydownIsVirtual(event)) + { + // Scroll up key presed? + if (event->data.keyDown.chr == vchrPageUp) + { + ListViewPageScroll (winUp); + handled = true; + } + + // Scroll down key presed? + else if (event->data.keyDown.chr == vchrPageDown) + { + ListViewPageScroll (winDown); + handled = true; + } + } + } + + else if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case ListNewButton: + if (CreateRecord ()) + FrmGotoForm (NewView); + handled = true; + break; + + case ListShowButton: + FrmPopupForm (OptionsDialog); + handled = true; + break; + } + } + + else if (event->eType == tblSelectEvent) + { + // An item in the list of messages was selected, display it. + CurrentRecord = TblGetRowID (event->data.tblSelect.pTable, + event->data.tblSelect.row); + FrmGotoForm (MessageView); + handled = true; + } + + else if (event->eType == menuEvent) + { + ListViewDoCommand (event->data.menu.itemID); + return (true); + } + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); +/* HandEra */ + if (vgaExists) + VgaFormModify(frm, vgaFormModify160To240); +/* end HandEra */ + ListViewInit (frm); + FrmDrawForm (frm); + ListViewSelectRecord (frm, CurrentRecord, true); + handled = true; + } + + else if (event->eType == frmUpdateEvent) + { + handled = ListViewUpdateDisplay (event->data.frmUpdate.updateCode); + } + + else if (event->eType == popSelectEvent) + { + ListViewChangeCategory (event->data.popSelect.selection); + } + + else if (event->eType == sclRepeatEvent) + { + ListViewScroll (event->data.sclRepeat.newValue - + event->data.sclRepeat.value); + } +/* HandEra */ + else if (event->eType == displayExtentChangedEvent) + { + ListViewResize(true); + handled = true; + } +/* end HandEra */ + return (handled); +} + + +/*********************************************************************** + * + * FUNCTION: ApplicationHandleEvent + * + * DESCRIPTION: This routine loads form resources and sets the event + * handler for the form loaded. + * + * 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. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/30/96 Initial Revision + * + ***********************************************************************/ +static Boolean ApplicationHandleEvent (EventPtr event) +{ + UInt16 formID; + FormPtr frm; + + if (event->eType == frmLoadEvent) + { + // Load the form resource. + formID = event->data.frmLoad.formID; + frm = FrmInitForm (formID); + FrmSetActiveForm (frm); + + // Set the event handler for the form. The handler of the currently + // active form is called by FrmDispatchEvent each time is receives an + // event. + switch (formID) + { + case ListView: + FrmSetEventHandler (frm, ListViewHandleEvent); + break; + + case MessageView: + FrmSetEventHandler (frm, MessageViewHandleEvent); + break; + + case NewView: + FrmSetEventHandler (frm, NewViewHandleEvent); + break; + + case EditView: + FrmSetEventHandler (frm, EditViewHandleEvent); + break; + + case ReplyDialog: + FrmSetEventHandler (frm, ReplyHandleEvent); + break; + + case DetailsDialog: + FrmSetEventHandler (frm, DetailsHandleEvent); + break; + + case OptionsDialog: + FrmSetEventHandler (frm, OptionsHandleEvent); + break; + + case PrefDialog: + FrmSetEventHandler (frm, PrefHandleEvent); + break; + + case SyncDialog: + FrmSetEventHandler (frm, SyncHandleEvent); + break; + + case TruncateDialog: + FrmSetEventHandler (frm, TruncateHandleEvent); + break; + + } + return (true); + } + return (false); +} + +/*********************************************************************** + * + * FUNCTION: PilotMain + * + * DESCRIPTION: This is the main entry point for the Mail application + * + * PARAMETERS: cmd - launch code + * cmdPBP - paramenter block (launch code specific) + * launchFlags - SysAppLaunch flags (ses SystemMgr.h) + * + * RETURNED: error code + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/30/96 Initial Revision + * MGolden 7/28/97 Added call to RomVersionCompatible + * jmp 10/18/99 If the default database image doesn't exist, then create + * an empty database. + * + ***********************************************************************/ +UInt32 PilotMain (UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags) +{ + UInt16 error; + MailAddRecordParamsType newMsg; + + + // This app makes use of PalmOS 2.0 features. It will crash if run on an + // earlier version of PalmOS. Detect and warn if this happens, then exit. + // Actually, require 4.0 ROM since that's what it's tested to run on. +#ifdef DO_ROM_CHECK + error = RomVersionCompatible (ourMinVersion, launchFlags); + if (error) + return error; +#endif + // Normal Launch + if (cmd == sysAppLaunchCmdNormalLaunch) + { + error = StartApplication (); + if (error) return (error); + + #if ERROR_CHECK_LEVEL == ERROR_CHECK_FULL + ECMailDBValidate (MailDB); + #endif + + if (NewRecord == noNewRecord) + FrmGotoForm (ListView); + else + FrmGotoForm (NewView); + EventLoop (); + + StopApplication (); + } + + + // This action code is sent to the app by the system when it is + // doing a text search. + else if (cmd == sysAppLaunchCmdFind) + { + Search ((FindParamsPtr)cmdPBP); + } + + + // This action code is sent to the app when the user hit the "Go To" + // button in the Find Results dialog. + else if (cmd == sysAppLaunchCmdGoTo) + { + Boolean launched; + launched = launchFlags & sysAppLaunchFlagNewGlobals; + + if (launched) + { + error = StartApplication (); + if (error) return (error); + + GoToItem ((GoToParamsPtr) cmdPBP, launched); + + EventLoop (); + StopApplication (); + } + else + GoToItem ((GoToParamsPtr) cmdPBP, launched); + } + + + else if (cmd == sysAppLaunchCmdSyncNotify) + { + ExgRegisterDatatype(sysFileCMail, exgRegSchemeID, "mailto", + "Email URL", 0); + SyncNotification (); + } + + + // This launch code is sent after the system is reset. We use this time + // to create our default database. If there is no default database image, + // then we create an empty database. + else if (cmd == sysAppLaunchCmdSystemReset) + { + if (((SysAppLaunchCmdSystemResetType*)cmdPBP)->createDefaultDB) + { + error = CreateDefaultDatabase(); + } + ExgRegisterDatatype(sysFileCMail, exgRegSchemeID, "mailto", + "Email URL", 0); + RegisterLocaleChangedNotification(); + } + + + // This action code is sent by the DesktopLink server when it creates + // a new database. We will initializes the new database. + else if (cmd == sysAppLaunchCmdInitDatabase) + { + MailAppInfoInit (((SysAppLaunchCmdInitDatabaseType*)cmdPBP)->dbP); + + // Set the backup bit. This is to aid syncs with non-Palm software. + SetDBBackupBit(((SysAppLaunchCmdInitDatabaseType*)cmdPBP)->dbP); + } + + + // This action code is sent by an other application when it want to + // add a record to the Mail outbox. + else if (cmd == sysAppLaunchCmdAddRecord) + { + error = AddMessage ((MailAddRecordParamsPtr)cmdPBP, true); + if (error) return (error); + } + + // This action code is sent by exchange manager when we want to + // open a mailto: url + else if (cmd == sysAppLaunchCmdGoToURL) + { + Char *buf; + UInt16 button; + buf = MemPtrNew(StrLen(cmdPBP)); + if(!buf) return memErrNotEnoughSpace; + error = ParseMailtoURL(&newMsg, cmdPBP, buf); + if (error) { + MemPtrFree(buf); + return (error); + } + button = FrmAlert (SaveDraftAlert); + if (button == SaveDraftYes) + error = AddMessage(&newMsg, false); + MemPtrFree(buf); + if (error) return (error); + } + else if (cmd == sysAppLaunchCmdNotify) + { + if (((SysNotifyParamType*)cmdPBP)->notifyType == sysNotifyLocaleChangedEvent) + { + DmSearchStateType searchState; + LocalID dbID; + UInt16 cardNo; + + // Since the locale has changed, delete the existing database + // and re-create it for the new locale + error = DmGetNextDatabaseByTypeCreator (true, &searchState, mailDBType, + sysFileCMail, true, &cardNo, &dbID); + if (!error) + DmDeleteDatabase(cardNo, dbID); + + error = CreateDefaultDatabase(); + + } + } + + return (errNone); + } +/*********************************************************************** + * + * FUNCTION: EventLoop + * + * DESCRIPTION: This routine is the event loop for the Mail + * aplication. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/30/96 Initial Revision + * + ***********************************************************************/ +static void EventLoop (void) +{ + UInt16 error; + EventType event; + + do + { + EvtGetEvent (&event, evtWaitForever); + + if (! SysHandleEvent (&event)) + + if (! MenuHandleEvent (NULL, &event, &error)) + + if (! ApplicationHandleEvent (&event)) + + FrmDispatchEvent (&event); + } + + while (event.eType != appStopEvent); +} + +/*********************************************************************** + * + * FUNCTION: PrvGetNameValuePair + * + * DESCRIPTION: Called from anyone that must parse name/value pairs. + * + * PARAMETERS: + * strP -> ptr to ptr to string holding HTML name/value pairs + * strLen -> ptr to Int16 holding length of string + * nameP -> ptr to ptr to location to store the resulting name string pointer + * nameLen -> ptr to Int16 to hold resulting nameP length + * valueP -> ptr to ptr to location to store the resulting value string pointer + * valueLen -> ptr to Int16 to hold resulting valueP length + * + * RETURNED: false if nothing found else true if found + * + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * tgh 4/23/98 Initial Version + * gcd 7/25/00 Move into Msg.c instead of INetLib + * + ***********************************************************************/ +static Boolean PrvGetNameValuePair(Char **strP, Int16 * strLen, Char **nameP, + Int16 * nameLen, Char **valueP, + Int16 * valueLen) +{ + Boolean result = false; + Int16 i, j, index = 0; + + if (*strLen == 0) + return false; + + *nameP = *strP; // assume name to be first character + + for (i = 0; i < *strLen; i++) + { + if ((*strP)[i] == '=') + { + index++; + break; + } + } + + *nameLen = i; // set the length of the name + *valueP = *strP + i + 1; // skip past the '=' sign + + for (j = 0; j < *strLen - i - 1; j++) + { + if ((*valueP)[j] == '&') + { + index++; + break; + } + } + + *valueLen = j; + + index += i + j; // name + value + '=' and/or '&' (if any) + if (index <= *strLen) + { + result = true; + *strP = *strP + index; + *strLen = *strLen - index; + } + + return result; +} + +/*********************************************************************** + * + * FUNCTION: ParseMailtoURL + * + * DESCRIPTION: Parse a mailto: url that exchange manager has given us + * + * PARAMETERS: newMsgP - MailAddRecordParamsType to fill in + * cmdPBP - parameter block + * + * RETURNED: error code + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * gcd 7/24/00 Initial Revision + ***********************************************************************/ +static Err ParseMailtoURL(MailAddRecordParamsPtr newMsgP, MemPtr cmdPBP, + Char *buf) +{ + Char *c, *nameP, *valueP; + Int16 strLen, nameLen, valueLen; + UInt16 i = 0; + + MemSet(newMsgP, sizeof(MailAddRecordParamsType), 0); + buf[0] = '\0'; + c = (Char *)StrChr((Char *)cmdPBP, ':'); + if(c) + { + c++; + while(*c && *c != '?') + buf[i++] = *c++; + buf[i] ='\0'; + newMsgP->to = buf; + if(*c == '?') + { + strLen = StrLen(c); + while (PrvGetNameValuePair(&c, &strLen, &nameP, &nameLen, &valueP, &valueLen)) + { + if(nameLen == 2 && (valueP) && + (!StrNCaselessCompare(nameP, "to", nameLen))) + { + StrNCat(&buf[i], valueP, valueLen); + newMsgP->to = &buf[i]; + i+=valueLen; + buf[i]='\0'; + } + if(nameLen == 7 && (valueP) && + (!StrNCaselessCompare(nameP, "subject", nameLen))) + { + StrNCat(&buf[i], valueP, valueLen); + newMsgP->subject = &buf[i]; + i+=valueLen; + buf[i]='\0'; + } + if(nameLen == 4 && (valueP) && + (!StrNCaselessCompare(nameP, "body", nameLen))) + { + StrNCat(&buf[i], valueP, valueLen); + newMsgP->body = &buf[i]; + i+=valueLen; + buf[i]='\0'; + } + } + } + return 0; + } + + return exgErrBadParam; +} + +/*********************************************************************** + * + * FUNCTION: TestAddRecord + * + * DESCRIPTION: Test the dd record function. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 1/23/97 Initial Revision + * + ***********************************************************************/ +/* +static void TestAddRecord (void) +{ + MailMessageParamsType params; + + + params.secret = false; + params.signature = true; + params.confirmRead = true; + params.confirmDelivery = true; + params.priority = priorityHigh; + params.subject = "Test two of add record"; + params.from = "Art Lamb"; + params.to = "To All"; + params.cc = "Copy"; + params.bcc = "Blind copy"; + params.replyTo = "Reply to"; + params.body = "This is a test"; + + AddMessage (¶ms, true); +} +*/ + +/*********************************************************************** + * + * FUNCTION: ListViewSelectRecord + * + * DESCRIPTION: Selects (highlights) a record on the table, scrolling + * to the record if neccessary. + * + * PARAMETERS: recordNum - record to select + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/11/97 select the current record in the list view if + * there is one. + * jmp 10/31/99 Allow scrollToSelect param to force a redraw + * of the currently selected record if necessary. + * + ***********************************************************************/ +static void ListViewSelectRecord (FormPtr frm, UInt16 recordNum, Boolean scrollToSelect) + { + Int16 row, column; + TablePtr tableP; + UInt16 attr; + + if (recordNum == -1) + return; + + ErrFatalDisplayIf (recordNum >= DmNumRecords(MailDB), "Record outside MailDB"); + + // Make sure that recordNum is in CurrentCategory + // Get the category and the secret attribute of the current record. + DmRecordInfo (MailDB, recordNum, &attr, NULL, NULL); + if ((attr & dmRecAttrCategoryMask) != CurrentCategory) + { + //the current record is not in the current category. Clear the current record global + CurrentRecord = noRecordSelected; + return; + } + + tableP = GetObjectPtr (ListTable); + + // Don't change anything if the same record is selected and we're not + // trying to force a selection. + if (TblGetSelection(tableP, &row, &column) && + recordNum == TblGetRowID (tableP, row) && + !scrollToSelect) + { + return; + } + + // See if the record is displayed by one of the rows in the table + // A while is used because if TblFindRowID fails we need to + // call it again to find the row in the reloaded table. + while (!TblFindRowID(tableP, recordNum, &row)) + { + if (!scrollToSelect) + return; + +/* + if (HideSecretRecords) + { + // If the record is hidden stop trying to show it. + DmRecordInfo(AddrDB, recordNum, &attr, NULL, NULL); + if (attr & dmRecAttrSecret) + { + return; + } + } +*/ + + // Scroll the view winDown placing the item + // on the top row + TopVisibleRecord = recordNum; + + //ListLoadTable(); + ListViewLoadTable (frm, TopVisibleRecord); + TblRedrawTable(tableP); + } + + // Select the item + TblSelectItem (tableP, row, 0); + }// + + +// ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ +//Branch Islands! + +/*********************************************************************** + * + * FUNCTION: GetObjectPtr + * + * DESCRIPTION: This routine returns a pointer to an object in the current + * form. + * + * PARAMETERS: formId - id of the form to display + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/30/96 Initial Revision + * + ***********************************************************************/ +void * GetObjectPtr (UInt16 objectID) +{ + FormPtr frm; + + frm = FrmGetActiveForm (); + return (FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, objectID))); + +} + +/*********************************************************************** + * + * FUNCTION: SearchDraw + * + * DESCRIPTION: This routine draw the address and subject of a message + * found by the text search routine. + * + * PARAMETERS: recordP - a mail record + * category - category the record is in + * r - draw region + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/27/96 Initial Revision + * CS2 10/17/00 Fix bug 42153: address is not displayed in results of [Find] + * + ***********************************************************************/ +static void SearchDraw (MailDBRecordPtr recordP, UInt16 category, RectanglePtr r) +{ + Char name [maxFindFromNameLen]; + Int16 x, y; + Int16 width; + + x = r->topLeft.x + 1; + y = r->topLeft.y; + width = ((r->extent.x - 2) / 2) - findColumnSpacing; + +/* CS2 (42153): revised logic: If there is a from address, use it, otherwise use the to + address. This should superset the previous behavior as outbox messages or draft messages + will lack Froms, inbox messages will have Froms, and deleted or filed messages will have + either Froms or Tos based on whether they were received messages or created messages. +*/ + + if ( *recordP->from ) + { + // Get the friendly name if there is one. + MailParseAddress( recordP->from, true, name, sizeof( name ) ); + DrawString( name, x, y, width ); + } + else if ( *recordP->to ) + { + DrawString( recordP->to, x, y, width ); + } + else + { + MemHandle missingH = DmGetResource( strRsc, noToListViewStrID ); + + if ( missingH ) + { + MemPtr missingP = MemHandleLock( missingH ); + + DrawString( missingP, x, y, width ); + + MemPtrUnlock( missingP ); + DmReleaseResource( missingH ); + } + } + +/* CS2 (42153): old logic + if (category == outboxCategory || category == draftCategory) + { + DrawString (recordP->to, x, y, width); + } + else if (*recordP->from) + { + // Get the friendly name if there is one. + MailParseAddress (recordP->from, true, name, sizeof (name)); + DrawString (name, x, y, width); + } + +*/ + + x += width + findColumnSpacing; + DrawString (recordP->subject, x, y, width); +} + +/*********************************************************************** + * + * FUNCTION: Search + * + * DESCRIPTION: This routine searchs the to do database for records + * contains the string passed. + * + * PARAMETERS: findParams - text search parameter block + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/27/96 Initial Revision + * MGolden 7/28/97 Added code from 2.0 sdk example for canceling the search + * jmp 10/21/99 Changed params to findParams to match other routines + * like this one. + * + ***********************************************************************/ +static void Search (FindParamsPtr findParams) +{ + Err err; + UInt16 pos; + UInt16 attr; + UInt16 cardNo = 0; + UInt16 fieldNum; + UInt16 recordNum; + Char * header; + Boolean done; + Boolean match; + MemHandle recordH; + MemHandle headerH; + LocalID dbID; + DmOpenRef dbP; + RectangleType r; + FindParamsPtr params; + MailDBRecordType record; + DmSearchStateType searchState; + UInt16 matchLength; + + params = (FindParamsPtr)findParams; + + // Find the application's data file. + err = DmGetNextDatabaseByTypeCreator (true, &searchState, mailDBType, + sysFileCMail, true, &cardNo, &dbID); + if (err) + { + findParams->more = false; + return; + } + + // Open the to do database. + dbP = DmOpenDatabase(cardNo, dbID, findParams->dbAccesMode); + if (!dbP) + { + findParams->more = false; + return; + } + + // Display the heading line. + headerH = DmGetResource (strRsc, findHeaderStrId); + header = MemHandleLock (headerH); + done = FindDrawHeader (findParams, header); + MemHandleUnlock(headerH); + if (done) + goto Exit; + + // Search the description and note fields for the "find" string. + recordNum = findParams->recordNum; + while (true) + { + // Because applications can take a long time to finish a find when + // the result may be on the screen or for other reasons, users like + // to be able to stop the find. Stop the find if an event is pending. + // This stops if the user does something with the device. Because + // this call slows winDown the search we perform it every so many + // records instead of every record. The response time should still + // be Int16 without introducing much extra work to the search. + + // Note that in the implementation below, if the next 16th record is + // secret the check doesn't happen. Generally this shouldn't be a + // problem since if most of the records are secret then the search + // won't take long anyway! + if ((recordNum & 0x000f) == 0 && // every 16th record + EvtSysEventAvail(true)) + { + // Stop the search process. + findParams->more = true; + break; + } + + recordH = DmQueryNextInCategory (dbP, &recordNum, dmAllCategories); + + // Have we run out of records? + if (! recordH) + { + findParams->more = false; + break; + } + + MailGetRecord (dbP, recordNum, &record, &recordH); + + // Search the description field, if a match is not found search the + // note field. + match = MsgSearch (&record, findParams->strToFind, &fieldNum, &pos, &matchLength); + if (match) + { + // Add the match to the find paramter block, if there is no room to + // display the match the following function will return true. + done = FindSaveMatch (findParams, recordNum, pos, fieldNum, matchLength, cardNo, dbID); + if (done) + { + MemHandleUnlock (recordH); + break; + } + + // Get the bounds of the region where we will draw the results. + FindGetLineBounds (findParams, &r); + + // Display the match. + DmRecordInfo (dbP, recordNum, &attr, NULL, NULL); + SearchDraw (&record, (attr & dmRecAttrCategoryMask), &r); + + findParams->lineNumber++; + } + + MemHandleUnlock (recordH); + recordNum++; + } + +Exit: + DmCloseDatabase (dbP); +} + +/*********************************************************************** + * + * FUNCTION: ListViewSelectFont + * + * DESCRIPTION: This routine handles selection of a font in the List + * View. + * + * PARAMETERS: currFontID - id of current font + * + * RETURNED: id of new font + * + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/10/97 Initial Revision + * + ***********************************************************************/ +static FontID SelectFont (FontID currFontID) +{ + UInt16 formID; + FontID fontID; + + formID = (FrmGetFormId (FrmGetActiveForm ())); + + // Call the OS font selector to get the id of a font. + fontID = FontSelect (currFontID); + + if (fontID != currFontID) + FrmUpdateForm (formID, updateFontChanged); + + return (fontID); +} + +/*********************************************************************** + * + * FUNCTION: ListViewNumberOfRows + * + * DESCRIPTION: This routine return the maximun number of visible rows, + * with the current list view font setting. + * + * PARAMETERS: table - List View table + * + * RETURNED: maximun number of displayable rows + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 8/28/97 Initial Revision + * + ***********************************************************************/ +static UInt16 ListViewNumberOfRows (TablePtr table) +{ + UInt16 rows; + UInt16 rowsInTable; + UInt16 tableHeight; + FontID currFont; + RectangleType r; + + + rowsInTable = TblGetNumberOfRows (table); + + TblGetBounds (table, &r); + tableHeight = r.extent.y; + + currFont = FntSetFont (ListFont); + rows = tableHeight / FntLineHeight (); + FntSetFont (currFont); + + if (rows <= rowsInTable) + return (rows); + else + return (rowsInTable); +} + +/*********************************************************************** + * + * FUNCTION: NewViewNumberOfRows + * + * DESCRIPTION: This routine return the maximun number of visible rows, + * with the current list view font setting. + * + * PARAMETERS: table - List View table + * + * RETURNED: maximun number of displayable rows + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 8/28/97 Initial Revision + * + ***********************************************************************/ +static UInt16 NewViewNumberOfRows (TablePtr table) +{ + UInt16 rows; + UInt16 rowsInTable; + UInt16 tableHeight; + FontID currFont; + RectangleType r; + + rowsInTable = TblGetNumberOfRows (table); + + TblGetBounds (table, &r); + tableHeight = r.extent.y; + + currFont = FntSetFont (EditFont); + rows = tableHeight / FntLineHeight (); + FntSetFont (currFont); + + if (rows <= rowsInTable) + return (rows); + else + return (rowsInTable); + }//NewViewNumberOfRows + +/*********************************************************************** + * + * FUNCTION: NewViewToggleFont + * + * DESCRIPTION: This routine changes the font used to display a note. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * MGolden 7/79/96 Initial Revision + * mgolden 10/6/97 changed for the rocky fonts + * + ***********************************************************************/ +static void NewViewToggleFont () + { + FontID originalFont = EditFont, newFont; + TablePtr table; + FormPtr frm; + + newFont = FontSelect (originalFont); + + if (newFont == originalFont) + return; + + frm = FrmGetActiveForm (); + table = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, NewTable)); + + TblReleaseFocus (table); + + // HACK! for some reason, the table does not erase the + // right edge of the underlined rows (of the edit fields!) + table->bounds.extent.x += 3; + TblEraseTable (table); + table->bounds.extent.x -= 3; + + + //change the table rect to be a direct multiple of the new line height? + table->bounds.extent.y = (gNewViewTableHeight / FntLineHeight ()) * FntLineHeight (); + + // DOLATER (bug 44154) - At this point, if there's a BCC field, and + // every field has two lines in it, and the font is getting changed + // from small to big, then the body row is no longer visible. This + // triggers a field error when the table tries to draw the body text, + // since it winds up creating a field with a height of zero. On release + // ROMs, the only problem is that the Body row label gets drawn over + // the top of the bottom-left button...which seems like a table clipping + // bug, but something that should be avoided in the app. So I think + // there are three useful changes that should be made to really fix + // this bug. (a) Modify the table drawing code to skip drawing a field + // when the field height is zero. Maybe report this as a non-fatal alert. + // (b) Modify the table code to not draw static text outside the bounds + // of the table - this might be a more general fix that covers both + // a & b. (c) Call a new routine here, which disabled/enables the body + // row based on whether it's visible. + + EditFont = newFont; + NewViewLoadTable(frm); + TblDrawTable (table); + NewViewRestoreEditState (); + }//NewViewToggleFont + +/*********************************************************************** + * + * FUNCTION: MailLoadPrefs + * + * DESCRIPTION: Load the preferences and MemHandle backward and forward + * compatibility + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * BGT 1/9/98 Initial Revision + * + ***********************************************************************/ +static void MailLoadPrefs(void) +{ + UInt16 prefsSize; + MailPreferenceType prefs; + Int16 prefsVersion; + UInt32 fontAttr; + + MessageFont = ListFont = EditFont = (FtrGet (sysFtrCreator, sysFtrDefaultFont, &fontAttr) == 0 ? (FontID) fontAttr : stdFont); + +/* HandEra */ + if (vgaExists) + MessageFont = ListFont = EditFont = VgaBaseToVgaFont(EditFont); +/* end HandEra */ + + prefsSize = sizeof (MailPreferenceType); + prefsVersion = PrefGetAppPreferences (sysFileCMail, mailPrefID, &prefs, &prefsSize, true); + if (prefsVersion > mailPrefsVersionNum) { + prefsVersion = noPreferenceFound; + } + if (prefsVersion != noPreferenceFound) + { + MessageFont = prefs.messageFont; + ListFont = prefs.listFont; + EditFont = prefs.editFont; + ShowDates = prefs.showDates; + IncludeOriginalText = prefs.includeOriginalText; + CommentOriginalText = prefs.commentOriginalText; + ConfirmDelete = prefs.confirmDelete; + ShowFullHeader = prefs.showFullHeader; + AttachSignature = prefs.attachSignature; + ConfirmRead = prefs.confirmRead; + ConfirmDelivery = prefs.confirmDelivery; + + //mgmg + MessageRevertCategory = prefs.revertCategory; + } +} + +/*********************************************************************** + * + * FUNCTION: MailSavePrefs + * + * DESCRIPTION: Save the preferences and prepare for backward compatibility + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * BGT 1/9/98 Initial Revision + * + ***********************************************************************/ +void MailSavePrefs(void) +{ + MailPreferenceType prefs; + + prefs.messageFont = MessageFont; + + prefs.listFont = ListFont; + prefs.editFont = EditFont; + + prefs.showDates = ShowDates; + prefs.includeOriginalText = IncludeOriginalText; + prefs.commentOriginalText = CommentOriginalText; + prefs.confirmDelete = ConfirmDelete; + prefs.showFullHeader = ShowFullHeader; + prefs.attachSignature = AttachSignature; + prefs.confirmRead = ConfirmRead; + prefs.confirmDelivery = ConfirmDelivery; + prefs.revertCategory = MessageRevertCategory; + + PrefSetAppPreferences (sysFileCMail, mailPrefID, mailPrefsVersionNum, + &prefs, sizeof (MailPreferenceType), true); +} + +#pragma mark - + +/*********************************************************************** + * + * FUNCTION: ToolsMoveObject + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + * REVISION HISTORY: + * + ***********************************************************************/ +void ToolsMoveObject(FormPtr frmP, UInt16 objIndex, Coord x_diff, Coord y_diff, Boolean draw) +{ + Coord old_x, old_y; + + if(draw) + FrmHideObject(frmP, objIndex); + + FrmGetObjectPosition(frmP, objIndex, &old_x, &old_y); + FrmSetObjectPosition(frmP, objIndex, old_x + x_diff, old_y + y_diff); + + if(draw) + FrmShowObject(frmP, objIndex); +} + +/*********************************************************************** + * + * FUNCTION: ToolsResizeObject + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + * REVISION HISTORY: + * + ***********************************************************************/ +void ToolsResizeObject(FormPtr frmP, UInt16 objIndex, Coord x_diff, Coord y_diff, Boolean draw) +{ + RectangleType r; + + if(draw) + FrmHideObject(frmP, objIndex); + + FrmGetObjectBounds(frmP, objIndex, &r); + r.extent.x += x_diff; + r.extent.y += y_diff; + FrmSetObjectBounds(frmP, objIndex, &r); + + if(draw) + FrmShowObject(frmP, objIndex); +} + + +/*********************************************************************** + * + * FUNCTION: ToolsFrmGetGSI + * + * DESCRIPTION: + * + * PARAMETERS: + * + * RETURNED: + * + * REVISION HISTORY: + * + ***********************************************************************/ +UInt16 ToolsFrmGetGSI(FormPtr frmP) +{ + UInt16 retval = -1; + UInt16 i, num; + + num = FrmGetNumberOfObjects(frmP); + + for (i=0;i +#include +#include "Mail.h" + +/************************************************************ + * DB initialization date + *************************************************************/ + +// DOLATER kwk - decide if this data should be put into a resource +// for localization into other languages. + +MailAppInfoType DefaultMailApplicationInfo = { + // Renamed categories + 0x000f, + + // Category labels + "Inbox", + "Outbox", + "Deleted", + "Filed", + "Draft", "", "", "", + "", "", "", "", + "", "", "", "", + + // Category Uniq IDs + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + + // Last Uniq ID + 15, + + // Reserved + 0, 0, + + // Dirty app info + 0xFFFF, + + // sort by priority, due date + sortByDate, + + // unsend message MemHandle + 0, + + // signature offset + sizeof (MailAppInfoType), + }; + + +/************************************************************ + * + * FUNCTION: ECMailDBValidate + * + * DESCRIPTION: This routine validates the integrity of the mail + * datebase. + * + * PARAMETERS: database pointer + * + * RETURNS: nothing + * + * CREATED: 11/6/96 + * + * BY: Art Lamb + * + *************************************************************/ +#if ERROR_CHECK_LEVEL == ERROR_CHECK_FULL + +void ECMailDBValidate (DmOpenRef dbP) +{ + UInt16 i; + UInt16 numRecord; + MemHandle recordH; + MailDBRecordType record; + + numRecord = DmNumRecords (dbP); + for (i = 0 ; i < numRecord; i++) + { + recordH = DmQueryRecord (dbP, i); + if (! recordH) continue; + + MailGetRecord (dbP, i, &record, &recordH); + + ErrFatalDisplayIf ((record.flags.priority > priorityLow), + "Invalid priority"); + + ErrFatalDisplayIf ((record.flags.addressing > sentBCC), + "Invalid addressing flag"); + + MemHandleUnlock (recordH); + } +} +#endif + + +/*********************************************************************** + * + * FUNCTION: DateCompare + * + * DESCRIPTION: This routine compares two dates. + * + * PARAMETERS: d1 - a date + * d2 - a date + * + * RETURNED: if d1 > d2 returns a positive int + * if d1 < d2 returns a negative int + * if d1 = d2 returns zero + * + * NOTE: This routine treats the DateType structure like an unsigned int, + * it depends on the fact the the members of the structure are ordered + * year, month, day form high bit to low low bit. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/12/95 Initial Revision + * + ***********************************************************************/ +static Int16 DateCompare (DateType d1, DateType d2) +{ + UInt16 int1, int2; + + int1 = DateToInt(d1); + int2 = DateToInt(d2); + + if (int1 > int2) + return (1); + else if (int1 < int2) + return (-1); + return 0; +} + +/*********************************************************************** + * + * FUNCTION: TimeCompare + * + * DESCRIPTION: This routine compares two times. "No time" is represented + * by minus one, and is considered less than all times. + * + * PARAMETERS: nothing + * + * RETURNED: if t1 > t2 returns a positive int + * if t1 < t2 returns a negative int + * if t1 = t2 returns zero + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/12/95 Initial Revision + * + ***********************************************************************/ +static Int16 TimeCompare (TimeType t1, TimeType t2) +{ + Int16 int1, int2; + + int1 = TimeToInt(t1); + int2 = TimeToInt(t2); + + if (int1 > int2) + return (1); + else if (int1 < int2) + return (-1); + return 0; + +} + + +/************************************************************ + * + * FUNCTION: CompareRecords + * + * DESCRIPTION: Compare two records. + * + * PARAMETERS: database record 1 + * database record 2 + * + * RETURNS: -n if record one is less (n != 0) + * n if record two is less + * + * CREATED: 1/23/95 + * + * BY: Roger Flores + * + * COMMENTS: Compare the two records key by key until + * there is a difference. Return -n if r1 is less or n if r2 + * is less. A zero is never returned because if two records + * seem identical then their unique IDs are compared! + * + * This function accepts record data chunk pointers to avoid + * requiring that the record be within the database. This is + * important when adding records to a database. This prevents + * determining if a record is a deleted record (which are kept + * at the end of the database and should be considered "greater"). + * The caller should test for deleted records before calling this + * function! + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * Roger Flores 1/23/95 Initial Revision + * MGolden 7/14/97 added sort by read at the end if the result was 0. + * + *************************************************************/ +static Int16 CompareRecords (MailPackedDBRecordPtr r1, MailPackedDBRecordPtr r2, + Int16 sortOrder, SortRecordInfoPtr UNUSED_PARAM(info1), + SortRecordInfoPtr UNUSED_PARAM(info2), MemHandle UNUSED_PARAM(appInfoH)) +{ + Int16 i; + Int16 result; + Char name1 [maxFriendlyNameLen]; + Char name2 [maxFriendlyNameLen]; + Char * p1; + Char * p2; + + // Sort high priority message to the top. + if (r1->flags.priority == priorityHigh || + r2->flags.priority == priorityHigh) + result = (Int16)r1->flags.priority - (Int16)r2->flags.priority; + else + result = 0; + + + if (result == 0) + { + // Sort by date + if (sortOrder == sortByDate) + { + result = DateCompare (r2->date, r1->date); + if (result == 0) + { + result = TimeCompare (r2->time, r1->time); + } + } + + // Sort by subject. + else if (sortOrder == sortBySubject) + result = StrCaselessCompare (&r1->firstField, &r2->firstField); + + // Sort by "from" field. + else + { + p1 = &r1->firstField; + p2 = &r2->firstField; + for (i = mailFieldSubject; i < mailFieldFrom; i++) + { + p1 += StrLen(p1) + 1; + p2 += StrLen(p2) + 1; + } + MailParseAddress (p1, true, name1, maxFriendlyNameLen); + MailParseAddress (p2, true, name2, maxFriendlyNameLen); + + result = StrCaselessCompare (name1, name2); + } + } + +//mgmg + if (result == 0) + { + //sort by the read flag + if (r2->flags.read != r1->flags.read) + { + if (r1->flags.read) + result = 1; + else + result = -1; + } + } + + return result; +} + + +/************************************************************ + * + * FUNCTION: FindSortPosition + * + * DESCRIPTION: Return where a record is or should be + * Useful to find or find where to insert a record. + * + * PARAMETERS: database record (not deleted!) + * + * RETURNS: the size in bytes + * + * CREATED: 5/30/96 + * + * BY: Art Lamb + * + *************************************************************/ +static UInt16 FindSortPosition (DmOpenRef dbP, MailPackedDBRecordPtr r) +{ + int sortOrder; + + sortOrder = MailGetSortOrder (dbP); + + return (DmFindSortPosition (dbP, r, NULL, (DmComparF *) CompareRecords, sortOrder)); +} + + +/************************************************************ + * + * FUNCTION: PackedRecordSize + * + * DESCRIPTION: Return the packed size of an MailDBRecordType + * + * PARAMETERS: database record + * + * RETURNS: the size in bytes + * + * CREATED: 5/30/96 + * + * BY: Art Lamb + * + *************************************************************/ +static UInt16 PackedRecordSize (MailDBRecordPtr r) +{ + UInt16 size; + + size = sizeof (MailPackedDBRecordType) + + (mailFieldBody - mailFieldSubject); + + if (r->subject != NULL) + size += StrLen (r->subject); + + if (r->from != NULL) + size += StrLen (r->from); + + if (r->to != NULL) + size += StrLen (r->to); + + if (r->cc != NULL) + size += StrLen (r->cc); + + if (r->bcc != NULL) + size += StrLen (r->bcc); + + if (r->replyTo != NULL) + size += StrLen (r->replyTo); + + if (r->sentTo != NULL) + size += StrLen (r->sentTo); + + if (r->body != NULL) + size += StrLen (r->body); + + return size; +} + + +/************************************************************ + * + * FUNCTION: PackRecord + * + * DESCRIPTION: Pack an MailDBRecordType + * + * PARAMETERS: database record + * + * RETURNS: the MailPackedDBRecord is packed + * + * CREATED: 5/30/96 + * + * BY: Art Lamb + * + *************************************************************/ +static void PackRecord (MailDBRecordPtr s, MailPackedDBRecordPtr d) +{ + UInt16 size; + Char zero = 0; + UInt32 offset = 0; + + + // Write date field. + DmWrite (d, offset, &s->date, sizeof(DateType)); + offset += sizeof (DateType); + + // Write time field. + DmWrite (d, offset, &s->time, sizeof(TimeType)); + offset += sizeof (TimeType); + + // Write flags field. + DmWrite (d, offset, &s->flags, sizeof(MailFlagsType)); + offset += sizeof (MailFlagsType); + + // Write subject field. + if (s->subject != NULL) + { + size = StrLen (s->subject) + 1; + DmWrite (d, offset, s->subject, size); + offset += size; + } + else + { + DmWrite (d, offset, &zero, 1); + offset++; + } + + // Write "from" field. + if (s->from != NULL) + { + size = StrLen (s->from) + 1; + DmWrite (d, offset, s->from, size); + offset += size; + } + else + { + DmWrite (d, offset, &zero, 1); + offset++; + } + + // Write "to" field. + if (s->to != NULL) + { + size = StrLen (s->to) + 1; + DmWrite (d, offset, s->to, size); + offset += size; + } + else + { + DmWrite (d, offset, &zero, 1); + offset++; + } + + // Write "cc" field. + if (s->cc != NULL) + { + size = StrLen (s->cc) + 1; + DmWrite (d, offset, s->cc, size); + offset += size; + } + else + { + DmWrite (d, offset, &zero, 1); + offset++; + } + + // Write "bcc" field. + if (s->bcc != NULL) + { + size = StrLen (s->bcc) + 1; + DmWrite (d, offset, s->bcc, size); + offset += size; + } + else + { + DmWrite (d, offset, &zero, 1); + offset++; + } + + // Write "reply to" field. + if (s->replyTo != NULL) + { + size = StrLen (s->replyTo) + 1; + DmWrite (d, offset, s->replyTo, size); + offset += size; + } + else + { + DmWrite (d, offset, &zero, 1); + offset++; + } + + // Write "sent to" field. + if (s->sentTo != NULL) + { + size = StrLen (s->sentTo) + 1; + DmWrite (d, offset, s->sentTo, size); + offset += size; + } + else + { + DmWrite (d, offset, &zero, 1); + offset++; + } + + // Write "body" field. + if (s->body != NULL) + { + size = StrLen (s->body) + 1; + DmWrite (d, offset, s->body, size); + offset += size; + } + else + { + DmWrite (d, offset, &zero, 1); + offset++; + } +} + + +/************************************************************ + * + * FUNCTION: MailUnpackRecord + * + * DESCRIPTION: Fills in the MailDBRecord structure + * + * PARAMETERS: database record + * + * RETURNS: the record unpacked + * + * CREATED: 5/30/96 + * + * BY: Art Lamb + * + *************************************************************/ +void MailUnpackRecord (MailPackedDBRecordPtr src, MailDBRecordPtr dest) +{ + char *p; + + + dest->date = src->date; + dest->time = src->time; + dest->flags = src->flags; + + p = &src->firstField; + + // Get the "subject" field. + if (*p) + { + dest->subject = p; + p += StrLen(p) + 1; + } + else + { + dest->subject = p; + p++; + } + + // Get the "from" field. + if (*p) + { + dest->from = p; + p += StrLen(p) + 1; + } + else + { + dest->from = p; + p++; + } + + // Get the "to" field. + if (*p) + { + dest->to = p; + p += StrLen(p) + 1; + } + else + { + dest->to = p; + p++; + } + + // Get the "cc" field. + if (*p) + { + dest->cc = p; + p += StrLen(p) + 1; + } + else + { + dest->cc = p; + p++; + } + + // Get the "bcc" field. + if (*p) + { + dest->bcc = p; + p += StrLen(p) + 1; + } + else + { + dest->bcc = p; + p++; + } + + // Get the "reply to" field. + if (*p) + { + dest->replyTo = p; + p += StrLen(p) + 1; + } + else + { + dest->replyTo = p; + p++; + } + + // Get the "sent to" field. + if (*p) + { + dest->sentTo = p; + p += StrLen(p) + 1; + } + else + { + dest->sentTo = p; + p++; + } + + // Get the "body" field. + if (*p) + { + dest->body = p; + p += StrLen(p) + 1; + } + else + { + dest->body = p; + p++; + } +} + + +/************************************************************ + * + * FUNCTION: MailLocalizeAppInfo + * + * DESCRIPTION: Look for localize app info strings and copy + * them into the app info block. + * + * PARAMETERS: application info ptr + * + * RETURNS: nothing + * + * CREATED: 12/13/95 + * + * BY: Roger Flores + * + *************************************************************/ +static void MailLocalizeAppInfo (MailAppInfoPtr appInfoP) +{ + MemHandle localizedAppInfoH; + Char * localizedAppInfoP; + MailAppInfoPtr nilP = 0; + MemHandle stringsH; + Char * *stringsP; + int i; + + + localizedAppInfoH = DmGetResource (appInfoStringsRsc, mailLocalizedAppInfoStr); + if (localizedAppInfoH) + { + localizedAppInfoP = MemHandleLock (localizedAppInfoH); + stringsH = SysFormPointerArrayToStrings (localizedAppInfoP, + dmRecNumCategories); + stringsP = MemHandleLock (stringsH); + + // Copy each category + for (i = 0; i < dmRecNumCategories; i++) + { + if (stringsP[i][0] != '\0') + DmStrCopy (appInfoP, (UInt32) nilP->categoryLabels[i], stringsP[i]); + } + + MemPtrFree (stringsP); + MemPtrFree (localizedAppInfoP); + } +} + + +/************************************************************ + * + * FUNCTION: MailAppInfoInit + * + * DESCRIPTION: Create an app info chunk if missing. Set + * the strings to a default. + * + * PARAMETERS: database pointer + * + * RETURNS: 0 if successful, errorcode if not + * + * CREATED: 1/20/95 + * + * BY: Roger Flores + * + *************************************************************/ +Err MailAppInfoInit (DmOpenRef dbP) +{ + UInt16 size; + UInt16 cardNo; + UInt16 wordValue; + MemHandle h; + LocalID dbID; + LocalID appInfoID; + MailAppInfoPtr nilP = 0; + MailAppInfoPtr appInfoP; + + if (DmOpenDatabaseInfo (dbP, &dbID, NULL, NULL, &cardNo, NULL)) + return dmErrInvalidParam; + + if (DmDatabaseInfo (cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, &appInfoID, NULL, NULL, NULL)) + return dmErrInvalidParam; + + if (appInfoID == 0) + { + // Add one for signature null-terminator. + size = sizeof (MailAppInfoType) + 1; + h = DmNewHandle (dbP, size); + if (! h) return dmErrMemError; + + appInfoID = MemHandleToLocalID (h); + DmSetDatabaseInfo(cardNo, dbID, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, &appInfoID, NULL, NULL, NULL); + } + + appInfoP = MemLocalIDToLockedPtr (appInfoID, cardNo); + + // Clear the app info block. + DmSet (appInfoP, 0, size, 0); + + // Initialize the categories. + CategoryInitialize ((AppInfoPtr) appInfoP, mailLocalizedAppInfoStr); + + // I don't know this field is used for. + wordValue = 0xFFFF; + DmWrite (appInfoP, (UInt32)&nilP->dirtyAppInfo, &wordValue, + sizeof(appInfoP->dirtyAppInfo)); + + // Initialize the sort order. + DmSet (appInfoP, (UInt32)&nilP->sortOrder, sizeof(appInfoP->sortOrder), + sortByDate); + + // Initialize the field the holds the index of the last unsent message. +// wordValue= noUnsendMessage; +// DmWrite (appInfoP, (UInt32)&nilP->unsentMessage, &wordValue, +// sizeof(appInfoP->unsentMessage)); + + // Initialize the offset of message signature. + wordValue = sizeof (MailAppInfoType); + DmWrite (appInfoP, (UInt32)&nilP->signatureOffset, &wordValue, + sizeof(appInfoP->signatureOffset)); + + // Initialize the message signature. + DmSet (appInfoP, appInfoP->signatureOffset, 1, 0); + + MemPtrUnlock (appInfoP); + + return 0; +} + + +/************************************************************ + * + * FUNCTION: MailGetAppInfo + * + * DESCRIPTION: Get the app info chunk + * + * PARAMETERS: database pointer + * + * RETURNS: MemHandle to the to do application info block (MailAppInfoType) + * + * CREATED: 5/12/95 + * + * BY: Art Lamb + * + *************************************************************/ +MemHandle MailGetAppInfo (DmOpenRef dbP) +{ + Err error; + UInt16 cardNo; + LocalID dbID; + LocalID appInfoID; + + error = DmOpenDatabaseInfo (dbP, &dbID, NULL, NULL, &cardNo, NULL); + ErrFatalDisplayIf (error, "Get getting app info"); + + error = DmDatabaseInfo (cardNo, dbID, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, &appInfoID, NULL, NULL, NULL); + ErrFatalDisplayIf (error, "Get getting app info"); + + return (MemLocalIDToGlobal (appInfoID, cardNo)); +} + + +/************************************************************ + * + * FUNCTION: MailGetSortOrder + * + * DESCRIPTION: This routine get the sort order value from the + * mail application info block. + * + * PARAMETERS: database pointer + * + * RETURNS: sort order: + * 0 - by date + * 1 - by subject + * 2 - by form + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 5/30/96 Initial Revision + * + *************************************************************/ +UInt8 MailGetSortOrder (DmOpenRef dbP) +{ + UInt8 sortOrder; + MailAppInfoPtr appInfoP; + + appInfoP = MemHandleLock (MailGetAppInfo (dbP)); + sortOrder = appInfoP->sortOrder; + MemPtrUnlock (appInfoP); + + return (sortOrder); +} + + +/************************************************************ + * + * FUNCTION: MailChangeSortOrder + * + * DESCRIPTION: Change the Mail Database's sort order + * + * PARAMETERS: database pointer + * TRUE if sort by company + * + * RETURNS: nothing + * + * CREATED: 1/17/95 + * + * BY: Roger Flores + * + *************************************************************/ +Err MailChangeSortOrder(DmOpenRef dbP, Boolean sortOrder) +{ + MailAppInfoPtr appInfoP; + MailAppInfoPtr nilP = 0; + UInt16 dirtyAppInfo; + + + appInfoP = MemHandleLock (MailGetAppInfo (dbP)); + + if (appInfoP->sortOrder != sortOrder) + { + dirtyAppInfo = appInfoP->dirtyAppInfo | mailSortByDirty; + DmWrite(appInfoP, (UInt32)&nilP->dirtyAppInfo, &dirtyAppInfo, sizeof(appInfoP->dirtyAppInfo)); + DmWrite(appInfoP, (UInt32)&nilP->sortOrder, &sortOrder, sizeof(appInfoP->sortOrder)); + + DmInsertionSort(dbP, (DmComparF *) &CompareRecords, (Int16) sortOrder); + } + + MemPtrUnlock (appInfoP); + + return 0; +} + + +/************************************************************ + * + * FUNCTION: MailSort + * + * DESCRIPTION: Sort the appointment database. + * + * PARAMETERS: database record + * + * RETURNS: nothing + * + * CREATED: 10/17/95 + * + * BY: Art Lamb + * + *************************************************************/ +void MailSort (DmOpenRef dbP) +{ + int sortOrder; + + sortOrder = MailGetSortOrder (dbP); + DmInsertionSort(dbP, (DmComparF *) &CompareRecords, (Int16) sortOrder); +} + + +/*********************************************************************** + * + * FUNCTION: MailGetUnsentMessage + * + * DESCRIPTION: This routine returns the ihndex of the unsent message, + * if there is one. If the application is exited while + * a new message is being edited, the MemHandle of the unsent + * message is save in the application info block. The + * record is not yet attached to the database index. + * + * PARAMETERS: dpP - database pointer + * + * RETURNED: unique id of a packed record or -1 + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/12/96 Initial Revision + * + ***********************************************************************/ +UInt32 MailGetUnsentMessage (DmOpenRef dbP) +{ + UInt32 uniqueID; + MailAppInfoPtr appInfoP; + + appInfoP = MemHandleLock (MailGetAppInfo (dbP)); + uniqueID = appInfoP->unsentMessage; + MemPtrUnlock (appInfoP); + + return (uniqueID); +} + + +/*********************************************************************** + * + * FUNCTION: MailSetUnsentMessage + * + * DESCRIPTION: This routine sets the index of the unsent message. + * If the application is exited while a new message + * is being edited, the index of the unsent message + * is save in the application info block. + * + * PARAMETERS: dpP - database pointer + * uniqueID - unique id of a packed record or -1 + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/12/96 Initial Revision + * + ***********************************************************************/ +void MailSetUnsentMessage (DmOpenRef dbP, UInt32 uniqueID) +{ + MailAppInfoPtr nilP = 0; + MailAppInfoPtr appInfoP; + + appInfoP = MemHandleLock (MailGetAppInfo (dbP)); + DmWrite(appInfoP, (UInt32)&nilP->unsentMessage, &uniqueID, + sizeof(appInfoP->unsentMessage)); + + MemPtrUnlock (appInfoP); +} + + +/*********************************************************************** + * + * FUNCTION: MailGetSignature + * + * DESCRIPTION: This routine returns a copy of the message signature + * string. This routine allocates a new MemHandle to hold + * signature, the caller is responsible for freeing this + * MemHandle. + * + * PARAMETERS: dpP - database pointer + * + * RETURNED: MemHandle of a signature or zero + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/25/96 Initial Revision + * + ***********************************************************************/ +MemHandle MailGetSignature (DmOpenRef dbP) +{ + UInt16 len; + Char * p; + Char * signatureP; + MemHandle h = 0; + MailAppInfoPtr appInfoP; + + appInfoP = MemHandleLock (MailGetAppInfo (dbP)); + + signatureP = ((Char *)appInfoP) + appInfoP->signatureOffset; + len = StrLen (signatureP); + + if (len) + { + h = MemHandleNew (len + 1); + p = MemHandleLock (h); + StrCopy (p, signatureP); + MemPtrUnlock (p); + } + + MemPtrUnlock (appInfoP); + + return (h); +} + + +/*********************************************************************** + * + * FUNCTION: MailParseAddress + * + * DESCRIPTION: This routine parses a mail address + * + * PARAMETERS: address - address string, ex: "art@palm (Art Lamb)" + * realName - if true return the name part, else return the + * address part + * buffer - buffer to hold return value + * len - length of buffer + * + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 06/12/96 Initial Revision + * kwk 12/02/98 Fixed bug w/calling TxtCharIsCntrl with bytes. + * + ***********************************************************************/ +void MailParseAddress (Char * address, Boolean realName, Char * buffer, + UInt16 bufferLen) +{ + UInt16 len; + Char* p; + Char* endP; + Char* startP; + + *buffer = 0; + + if (realName) + { + // Get the name portion of the string passed. + endP = StrChr (address, linefeedChr); + if (! endP) + endP = StrChr (address, 0); + + startP = StrChr (address, '('); + + if (startP && startP < endP) + { + startP++; + len = endP - startP; + while (endP-- > startP) + { + if (*endP == ')') + { + len = endP - startP; + break; + } + } + if (len > bufferLen - 1) + len = bufferLen - 1; + + p = buffer; + while (len--) + { + *p++ = *startP++; + } + *p = 0; + } + } + + if (*buffer == 0) + { + len = 0; + while (true) + { + WChar theChar; + address += TxtGetNextChar(address, 0, &theChar); + if (TxtCharIsCntrl(theChar) || (theChar == chrLeftParenthesis)) + break; + else if (len + TxtCharSize(theChar) > bufferLen - 1) + break; + else + len += TxtSetNextChar(buffer, len, theChar); + } + + buffer[len] = 0; + + // Remove trailing spaces. + while (len) + { + WChar theChar; + len -= TxtGetPreviousChar(buffer, len, &theChar); + if (TxtCharIsSpace(theChar)) + buffer[len] = 0; + else + break; + } + } +} + + +/************************************************************ + * + * FUNCTION: MailNewRecord + * + * DESCRIPTION: Create a new packed record. The new record is + * + * PARAMETERS: database pointer + * database record + * + * RETURNS: record MemHandle or 0 if error + * + * CREATED: 6/6/96 + * + * BY: Art Lamb + * + *************************************************************/ +Err MailNewRecord (DmOpenRef dbP, MailDBRecordPtr r, UInt16 *indexP) +{ + Err err; + UInt16 index; + MemHandle recordH; + MailPackedDBRecordPtr recordP; + + // Make a new chunk with the correct size. + recordH = DmNewHandle (dbP, (UInt32) PackedRecordSize (r)); + if (recordH == NULL) + return dmErrMemError; + + // Copy the data from the unpacked record to the packed one. + recordP = MemHandleLock (recordH); + PackRecord (r, recordP); + + // Determine the sort position of the new record. + index = FindSortPosition (dbP, recordP); + + MemPtrUnlock (recordP); + + err = DmAttachRecord (dbP, &index, recordH, 0); + if (err) + MemHandleFree (recordH); + else + *indexP = index; + + return (err); +} + + +/************************************************************ + * + * FUNCTION: MailAttachRecord + * + * DESCRIPTION: Attach a packed record in sorted position. + * + * PARAMETERS: database pointer + * database record MemHandle + * + * RETURNS: 0 if successful, error code if not + * + * CREATED: 6/6/96 + * + * BY: Art Lamb + * + *************************************************************/ +Err MailAttachRecord (DmOpenRef dbP, MemHandle recordH, UInt16 * indexP) +{ + Err err; + UInt16 index; + MailPackedDBRecordPtr recordP; + + recordP = MemHandleLock (recordH); + + index = FindSortPosition (dbP, recordP); + + MemPtrUnlock (recordP); + + err = DmAttachRecord (dbP, &index, recordH, 0); + if (err) + MemHandleFree (recordH); + else + *indexP = index; + + return err; +} + + +/************************************************************ + * + * FUNCTION: MailGetRecord + * + * DESCRIPTION: Get a record from a Mail database + * + * PARAMETERS: database pointer + * database index + * database record + * + * RETURNS: 0 if successful, errorcode if not + * + * CREATED: 5/12/95 + * + * BY: Art Lamb + * + *************************************************************/ +Err MailGetRecord (DmOpenRef dbP, UInt16 index, MailDBRecordPtr r, + MemHandle * handleP) +{ + MemHandle handle; + MailPackedDBRecordPtr src; + + + handle = DmQueryRecord(dbP, index); + ErrFatalDisplayIf(DmGetLastErr(), "Error Querying record"); + + src = (MailPackedDBRecordPtr) MemHandleLock (handle); + + if (DmGetLastErr()) + { + *handleP = 0; + return DmGetLastErr(); + } + + MailUnpackRecord (src, r); + + *handleP = handle; + return 0; +} + + +/************************************************************ + * + * FUNCTION: MailChangeRecord + * + * DESCRIPTION: Change a record in the Appointment Database + * + * PARAMETERS: database pointer + * database index + * database record + * changed fields + * + * RETURNS: 0 if successful, errorcode if not + * + * RETURNS: 0 if successful, errorcode if not + * + * CREATED: 5/12/95 + * + * 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 MailChangeRecord (DmOpenRef dbP, UInt16 * index, MailDBRecordPtr r, + MailChangedFieldsType changedFields) +{ + Err result; + Int16 newIndex; + UInt16 attributes; + Boolean dontMove; + MemHandle oldH; + MemHandle srcH; + MemHandle dstH; + MailDBRecordType src; + MailPackedDBRecordPtr dst; + MailPackedDBRecordPtr cmp; + + // We do not assume that r is completely valid so we get a valid + // MailDBRecordPtr... + if ((result = MailGetRecord(dbP, *index, &src, &srcH)) != 0) + return result; + + // and we apply the changes to it. + if (changedFields.date) + src.date = r->date; + + if (changedFields.time) + src.time = r->time; + + if (changedFields.flags) + src.flags = r->flags; + + if (changedFields.subject) + src.subject = r->subject; + + if (changedFields.from) + src.from = r->from; + + if (changedFields.to) + src.to = r->to; + + if (changedFields.cc) + src.cc = r->cc; + + if (changedFields.bcc) + src.bcc = r->bcc; + + if (changedFields.replyTo) + src.replyTo = r->replyTo; + + if (changedFields.sentTo) + src.sentTo = r->sentTo; + + if (changedFields.body) + src.body = r->body; + + + // Allocate a new chunk with the correct size and pack the data from + // the unpacked record into it. + dstH = DmNewHandle(dbP, (UInt32) PackedRecordSize (&src)); + if (dstH) + { + dst = MemHandleLock (dstH); + PackRecord (&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.date) && + (! changedFields.time) && + (! changedFields.subject) && + (! changedFields.from)) + goto attachRecord; + + + // 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 = (CompareRecords (cmp, dst, 0, NULL, NULL, 0) == -1); + 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 &= (CompareRecords (dst, cmp, 0, NULL, NULL, 0) == -1); + MemPtrUnlock (cmp); + } + } + + if (dontMove) + goto attachRecord; + + + // The record isn't in the right position. Move it. + newIndex = FindSortPosition (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: GetRecordField + * + * DESCRIPTION: This routine changes a field of the passed record. + * + * PARAMETERS: dpP - database pointer + * recordField - fields to chance + * data - new field value + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/17/96 Initial Revision + * + ***********************************************************************/ +static void * GetRecordField (MailDBRecordPtr recordP, + MailRecordFieldType recordField) +{ + void * ptr; + + switch (recordField) + { + case mailFieldSubject: + ptr = recordP->subject; + break; + + case mailFieldFrom: + ptr = recordP->from; + break; + + case mailFieldTo: + ptr = recordP->to; + break; + + case mailFieldCC: + ptr = recordP->cc; + break; + + case mailFieldBCC: + ptr = recordP->bcc; + break; + + case mailFieldReplyTo: + ptr = recordP->replyTo; + break; + + case mailFieldSentTo: + ptr = recordP->sentTo; + break; + + case mailFieldBody: + ptr = recordP->body; + break; + + default: + ErrDisplay ("Invalid record field"); + } + + return (ptr); +} + + +/*********************************************************************** + * + * FUNCTION: MailChangeRecordField + * + * DESCRIPTION: This routine changes a field of the passed record. + * + * PARAMETERS: dpP - database pointer + * hP - pointer to the MemHandle of a packed database + * record. A new MemHandle may be returned as + * the result of resizing the record. + * recordField - fields to chance + * + * RETURNED: nothing + * + * COMMENTS: This routine does not move the modified record to to + * correct sort position if one of the sort key field is + * modified. This function is intented for use on + * records that have not been attached to the database. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/11/96 Initial Revision + * + ***********************************************************************/ +/* +Err MailChangeRecordField (DmOpenRef dbP, UInt16 index, + MailRecordFieldType recordField, void * data) +{ + Err err = 0; + UInt16 newSize; + UInt16 oldSize; + MemHandle recordH; + MailDBRecordType record; + MailPackedDBRecordPtr r; + + + recordH = DmQueryRecord (dbP, index);; + r = MemHandleLock (recordH); + MailUnpackRecord (r, &record); + oldSize = PackedRecordSize (&record); + + ChangeRecordField (&record, recordField, data); + + newSize = PackedRecordSize (&record); + + // If the record the same size? + if (oldSize == newSize) + { + PackRecord (&record, r); + MemPtrUnlock (r); + } + + // Is the record smaller? + else if (oldSize > newSize) + { + PackRecord (&record, r); + MemPtrUnlock (r); + err = MemHandleResize (recordH, newSize); + } + + // The record is larger. + else + { + MemPtrUnlock (r); + + recordH = DmResizeRecord (dbP, index, newSize); + if (! recordH) return (err); + + r = MemHandleLock (recordH); + MailUnpackRecord (r, &record); + ChangeRecordField (&record, recordField, data); + PackRecord (&record, r); + MemPtrUnlock (r); + } + + return (err); +} +*/ + +/*********************************************************************** + * + * FUNCTION: MailInsertIntoField + * + * DESCRIPTION: This routine inserts the passed string into the + * specified a field of the passed record. + * + * PARAMETERS: dpP - database pointer + * index - index of a packed database record + * recordField - fields to insert into + * insertData - string to insert + * insertLen - length of insert string + * insertOffset - offset from start of field to insert at + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/17/96 Initial Revision + * + ***********************************************************************/ +Err MailInsertIntoField (DmOpenRef dbP, UInt16 index, + MailRecordFieldType recordField, Char * insertData, UInt16 insertLen, + UInt16 insertOffset) +{ + Err err = 0; + UInt16 newSize; + UInt16 oldSize; + UInt32 offset; + UInt32 bytes; + Char * ptr; + UInt16 * srcP=0, dstP=0; + MemHandle recordH; + MailDBRecordType record; + MailPackedDBRecordPtr r; + + + if (! insertLen) return (0); + + // Resize the record. + recordH = DmQueryRecord (dbP, index);; + oldSize = MemHandleSize (recordH); + newSize = oldSize + insertLen; + recordH = DmResizeRecord (dbP, index, newSize); + if (recordH == NULL) + return dmErrMemError; + + + r = MemHandleLock (recordH); + MailUnpackRecord (r, &record); + + switch (recordField) + { + case mailFieldSubject: + ptr = record.subject; + break; + + case mailFieldFrom: + ptr = record.from; + break; + + case mailFieldTo: + ptr = record.to; + break; + + case mailFieldCC: + ptr = record.cc; + break; + + case mailFieldBCC: + ptr = record.bcc; + break; + + case mailFieldReplyTo: + ptr = record.replyTo; + break; + + case mailFieldSentTo: + ptr = record.sentTo; + break; + + case mailFieldBody: + ptr = record.body; + break; + + default: + ErrDisplay ("Invalid record field"); + } + + + // Move the rest of the record. + ptr += insertOffset; + offset = (ptr - (Char *)r) + insertLen; + bytes = oldSize - (UInt32)(ptr - (Char *)r); + if (bytes) + DmWrite (r, offset, ptr, bytes); + + // Write the new field. + offset = (ptr - (Char *)r); + DmWrite (r, offset, insertData, insertLen); + + MemHandleUnlock (recordH); + + + return (err); +} + +/************************************************************ + * + * FUNCTION: MailSortRecord + * + * DESCRIPTION: Move the passed record to its correct sort + * position. + * + * PARAMETERS: database pointer + * record index + * + * RETURNS: zero if successful, errorcode if not + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/18/96 Initial Revision + * + *************************************************************/ +Err MailSortRecord (DmOpenRef dbP, UInt16 * indexP) +{ + Err err; + Int16 sortOrder; + UInt16 index; + UInt16 attributes; + UInt32 uniqueID; + MemHandle recordH; + Boolean dontMove; + MailPackedDBRecordPtr cmp; + MailPackedDBRecordPtr recordP; + + sortOrder = MailGetSortOrder (dbP); + + // Check if the record is already in the correct position. + recordP = MemHandleLock (DmQueryRecord (dbP, *indexP)); + if (*indexP > 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, *indexP-1)); + dontMove = (CompareRecords (cmp, recordP, sortOrder, NULL, NULL, 0) <= 0); + MemPtrUnlock (cmp); + } + else + dontMove = true; + + if (dontMove && (*indexP+1 < DmNumRecords (dbP))) + { + DmRecordInfo(dbP, *indexP+1, &attributes, NULL, NULL); + if ( ! (attributes & dmRecAttrDelete) ) + { + cmp = MemHandleLock (DmQueryRecord (dbP, *indexP+1)); + dontMove &= (CompareRecords (recordP, cmp, sortOrder, NULL, NULL, 0) <= 0); + MemPtrUnlock (cmp); + } + } + MemPtrUnlock (recordP); + + if (dontMove) return (0); + + + // Since the routine that determines the records sort position uses a + // binary search algorythm we need to remove the record from the database + // before we can determine its new position. We will also save and restore the + // record's attributes and unique ID. + DmRecordInfo (dbP, *indexP, &attributes, &uniqueID, NULL); + + err = DmDetachRecord (dbP, *indexP, &recordH); + if (err) return (err); + + recordP = MemHandleLock (recordH); + index = DmFindSortPosition (dbP, recordP, NULL, (DmComparF *) CompareRecords, sortOrder); + MemPtrUnlock (recordP); + + err = DmAttachRecord (dbP, &index, recordH, 0); + if (err) return (err); + + DmSetRecordInfo (dbP, index, &attributes, &uniqueID); + + *indexP = index; + + return (err); +} + + +/*********************************************************************** + * + * FUNCTION: MailChangeRecordField + * + * DESCRIPTION: This routine changes a field of the passed record. + * + * PARAMETERS: dpP - database pointer + * hP - pointer to the MemHandle of a packed database + * record. A new MemHandle may be returned as + * the result of resizing the record. + * recordField - fields to chance + * + * RETURNED: nothing + * + * COMMENTS: This routine does not move the modified record to to + * correct sort position if one of the sort key field is + * modified. This function is intented for use on + * records that have not been attached to the database. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/17/96 Initial Revision + * + ***********************************************************************/ +Err MailChangeRecordField (DmOpenRef dbP, UInt16 * indexP, + MailRecordFieldType recordField, void * data) +{ + Err err = 0; + UInt16 newSize; + UInt16 curSize; + UInt32 offset; + UInt32 bytes; + Char * ptr; + Char * fieldP; + MemHandle recordH; + MailDBRecordType record; + MailPackedDBRecordPtr r; + MailPackedDBRecordPtr nilP = 0; + + // Get the record which we are going to change + recordH = DmQueryRecord (dbP, *indexP);; + r = MemHandleLock (recordH); + + + // We MemHandle the fixed size fields here. + switch (recordField) + { + case mailFieldDate: + DmWrite (r, (UInt32)&nilP->date, data, sizeof(r->date)); + goto sort; + + case mailFieldTime: + DmWrite (r, (UInt32)&nilP->time, data, sizeof(r->time)); + goto sort; + + case mailFieldFlags: + DmWrite (r, (UInt32)&nilP->flags, data, sizeof(r->flags)); + goto sort; + } + + + + // Calculate the size of the changed record + MailUnpackRecord (r, &record); + fieldP = GetRecordField (&record, recordField); + curSize = MemPtrSize (r); + newSize = curSize + StrLen (data) - StrLen (fieldP); + + + // If the new record is longer, expand the record. + if (newSize > curSize) + { + MemPtrUnlock (r); + + recordH = DmResizeRecord (dbP, *indexP, newSize); + if (! recordH) return (dmErrMemError); + + r = MemHandleLock (recordH); + MailUnpackRecord (r, &record); + } + + + // Change the record field. First Move the rest of the record. + fieldP = GetRecordField (&record, recordField); + offset = (fieldP - (Char *)r) + StrLen (data) + 1; + ptr = fieldP + StrLen (fieldP) + 1; + bytes = curSize - (UInt32)(ptr - (Char *)r); + if (bytes) + DmWrite (r, offset, ptr, bytes); + + // Write the new field. + offset = (fieldP - (Char *)r); + DmStrCopy (r, offset, data); + + + // If the new record is shorter, shrink the record. + if (newSize < curSize) + MemPtrResize (r, newSize); + + +sort: + MemPtrUnlock (r); + + + // If the sort position is changed move to the new position. + // Check if any of the key fields have changed. + switch (recordField) + { + case mailFieldDate: + case mailFieldTime: + case mailFieldSubject: + case mailFieldFrom: + err = MailSortRecord (dbP, indexP); + } + + + return err; +} + + +/*********************************************************************** + * + * FUNCTION: MailGetDatabase + * + * DESCRIPTION: Get the application's database. Open the database if it + * exists, create it if neccessary. + * + * PARAMETERS: *dbPP - pointer to a database ref (DmOpenRef) to be set + * mode - how to open the database (dmModeReadWrite) + * + * RETURNED: Err - zero if no error, else the error + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * jmp 10/18/99 Initial Revision + * + ***********************************************************************/ +Err MailGetDatabase (DmOpenRef *dbPP, UInt16 mode) +{ + Err error = errNone; + DmOpenRef dbP; + UInt16 cardNo; + LocalID dbID; + + *dbPP = NULL; + + // Find the application's data file. If it doesn't exist create it. + dbP = DmOpenDatabaseByTypeCreator (mailDBType, sysFileCMail, mode); + if (!dbP) + { + error = DmCreateDatabase (0, mailDBName, sysFileCMail, mailDBType, false); + if (error) + return error; + + dbP = DmOpenDatabaseByTypeCreator(mailDBType, sysFileCMail, mode); + if (!dbP) + return (1); + + // Set the backup bit. This is to aid syncs with non-Palm software. + SetDBBackupBit(dbP); + + error = MailAppInfoInit (dbP); + if (error) + { + DmOpenDatabaseInfo(dbP, &dbID, NULL, NULL, &cardNo, NULL); + DmCloseDatabase(dbP); + DmDeleteDatabase(cardNo, dbID); + return error; + } + } + + *dbPP = dbP; + return 0; +} diff --git a/handera-sdk-105/examples/Mail/Src/MailDB.h b/handera-sdk-105/examples/Mail/Src/MailDB.h new file mode 100644 index 0000000..4ca18ac --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/MailDB.h @@ -0,0 +1,228 @@ +/****************************************************************************** + * + * Copyright (c) 1996-1999 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MailDB.h + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This file defines the database structures and functions of the Mail + * application. + * + * History: + * May 30, 1996 Created by Art Lamb + * + *****************************************************************************/ + +/************************************************************ + * + * Mail database constants. + * + *************************************************************/ + +// String resource used to initialize application info block. +#define mailLocalizedAppInfoStr 1000 + +// Dirty flags for to do application info +#define mailSortByDirty 0x0001 + + +// Sort orders +#define sortByDate 0 +#define sortByFrom 1 +#define sortBySubject 2 + + +#define noUnsendMessage -1 + +/************************************************************ + * + * Mail database structures. + * + *************************************************************/ + +// The format of a packed mail record is as follows: +// +// DateType date; +// TimeType time; +// MailDBRecordFlags flags; +// char [] subject; // null terminated +// char [] from; // null terminated +// char [] to; // null terminated +// char [] cc; // null terminated +// char [] bcc; // null terminated +// char [] replyTo; // null terminated +// char [] sentTo; // null terminated +// char [] body; // null terminated + + +// Application info block +typedef struct { + UInt16 renamedCategories; // bitfield of categories with a different name + char categoryLabels [dmRecNumCategories] [dmCategoryLength]; + UInt8 categoryUniqIDs [dmRecNumCategories]; + UInt8 lastUniqID; // Uniq IDs generated by the device are between + // 0 - 127. Those from the PC are 128 - 255. + UInt8 reserved1; // from the compiler word aligning things + UInt16 reserved2; + UInt16 dirtyAppInfo; + UInt8 sortOrder; + UInt8 reserved3; + UInt32 unsentMessage; // unique id of unsend message. + UInt16 signatureOffset; +} MailAppInfoType; + +typedef MailAppInfoType * MailAppInfoPtr; + +typedef enum { priorityHigh, priorityNormal, priorityLow } MailPriorityType; + +typedef enum { sentTo, sentCC, sentBCC } MailAddressingType; + +typedef struct { + UInt16 read : 1; + UInt16 signature : 1; + UInt16 confirmRead : 1; + UInt16 confirmDelivery : 1; + UInt16 priority : 2; // MailPriorityType + UInt16 addressing : 2; // MailAddressingType + UInt16 reserved : 8; +} MailFlagsType; + + +// The following structure doesn't really exist. The first field +// varies depending on the data present. However, it is convient +// (and less error prone) to use when accessing the other information. +typedef struct { + DateType date; + TimeType time; + MailFlagsType flags; + Char firstField; + UInt8 reserved; +} MailPackedDBRecordType; + +typedef MailPackedDBRecordType * MailPackedDBRecordPtr; + + +// MailItemType +// +// This is the format of a to do record used by the application. All +// pointers are either NULL or point to data within the PackedDB record. +// All strings are null character terminated. +typedef struct { + DateType date; + TimeType time; + MailFlagsType flags; + Char * subject; + Char * from; + Char * to; + Char * cc; + Char * bcc; + Char * replyTo; + Char * sentTo; + Char * body; +} MailDBRecordType; + +typedef MailDBRecordType * MailDBRecordPtr; + + + +//This structure should match the order of the fields in the record. +typedef enum { + mailFieldDate, + mailFieldTime, + mailFieldFlags, + mailFieldSubject, + mailFieldFrom, + mailFieldTo, + mailFieldCC, + mailFieldBCC, + mailFieldReplyTo, + mailFieldSentTo, + mailFieldBody } MailRecordFieldType; + + +// Used by MailChangeRecord function. +typedef struct { + unsigned date :1; + unsigned time :1; + unsigned flags :1; + unsigned subject :1; + unsigned from :1; + unsigned to :1; + unsigned cc :1; + unsigned bcc :1; + unsigned replyTo :1; + unsigned sentTo :1; + unsigned body :1; +} MailChangedFieldsType; + + + + +/************************************************************ + * + * Mail database routines. + * + *************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + + +Err MailAppInfoInit (DmOpenRef dbP); + +MemHandle MailGetAppInfo (DmOpenRef dbP); + +UInt8 MailGetSortOrder (DmOpenRef dbP); + +Err MailChangeSortOrder (DmOpenRef dbP, UInt8 sortOrder); + +void MailSort (DmOpenRef dbP); + +UInt32 MailGetUnsentMessage (DmOpenRef dbP); + +void MailSetUnsentMessage (DmOpenRef dbP, UInt32 uniqueID); + +MemHandle MailGetSignature (DmOpenRef dbP); + +void MailSetSignature (DmOpenRef dbP, MemHandle h); + + + +void MailParseAddress (Char * address, Boolean realName, Char * buffer, + UInt16 bufferLen); + +Err MailNewRecord (DmOpenRef dbP, MailDBRecordPtr r, UInt16 *indexP); + +Err MailAttachRecord (DmOpenRef dbP, MemHandle recordH, UInt16 * indexP); + +Err MailGetRecord (DmOpenRef dbP, UInt16 index, MailDBRecordPtr r, + MemHandle * handleP); + +Err MailChangeRecord (DmOpenRef dbP, UInt16 * index, + MailDBRecordPtr r, MailChangedFieldsType changedFields); + +void MailUnpackRecord (MailPackedDBRecordPtr src, MailDBRecordPtr dest); + +Err MailChangeRecordField (DmOpenRef dbP, UInt16 * indexP, + MailRecordFieldType recordField, void * data); + +Err MailInsertIntoField (DmOpenRef dbP, UInt16 index, + MailRecordFieldType recordField, Char * insertData, + UInt16 insertLen, UInt16 insertOffset); + +Err MailSortRecord (DmOpenRef dbP, UInt16 * indexP); + + +void ECMailDBValidate (DmOpenRef dbP); + + +Err MailGetDatabase (DmOpenRef *dbPP, UInt16 mode); + + + +#ifdef __cplusplus +} +#endif diff --git a/handera-sdk-105/examples/Mail/Src/MailLookup.c b/handera-sdk-105/examples/Mail/Src/MailLookup.c new file mode 100644 index 0000000..128a01f --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/MailLookup.c @@ -0,0 +1,142 @@ +/****************************************************************************** + * + * Copyright (c) 1996-2000 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MailLookup.c + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This is the Mail application's main module. + * + * History: + * June 26, 1996 Created by Art Lamb + * + *****************************************************************************/ + +#include + +#include "Mail.h" + +/*********************************************************************** + * + * FUNCTION: AddressLookup + * + * DESCRIPTION: This routine initializes a row of the "Edit View" table. + * + * PARAMETERS: fld - + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 06/26/96 Initial Revision + * meg 10/09/98 free the resultH to avoid a memory leak + * kwk 12/04/98 Modified to work for Japanese, plus fixed logic + * bug w/deciding when to search right for end of word. + * LFe 09/18/00 Use the new PhoneLookup Api + * CS2 12/01/00 Pick format string based on whether it's the first address or not + * + ***********************************************************************/ + +void AddressLookup (FieldPtr fld) +{ + MemHandle formatH; + MemHandle buttonH; + MemHandle titleH; + Char *textP; + UInt32 wordStart, wordEnd, leftPos, textLen; + AddrLookupParamsType params; + UInt16 titleStrID, insPtPos; + Boolean firstAddress; + + MemSet(¶ms, sizeof(params), 0); + + switch (EditViewField) + { + case editToField: titleStrID = mailToLookupTitleStrID; break; + case editFromField: titleStrID = mailFromLookupTitleStrID; break; + case editCCField: titleStrID = mailCCLookupTitleStrID; break; + case editBCCField: titleStrID = mailBCCLookupTitleStrID; break; + } + + /* CS2 (43813): for the first address, we don't want a comma but for additional + addresses, we do want to prepend a comma. Choose the appropriate format string. + + If the field has no text, we're the first address. + If we're within or adjacent to the first word in the field, we're the first address. + Otherwise, we're not the first address. + */ + + firstAddress = false; + textP = FldGetTextPtr( fld ); + if ( NULL != textP ) + { + /* This code is taken from PhoneLookup itself, we want to use the same word-finding + algorithm. This duplicates some work but is the only way. + */ + insPtPos = FldGetInsPtPosition( fld ); + leftPos = insPtPos; + + /* If we're not at the start of the field, check word boundaries. */ + if ( 0 < leftPos ) + { + leftPos -= TxtPreviousCharSize( textP, insPtPos ); + + textLen = FldGetTextLength( fld ); + + /* Look to the left of the insertion point first, then to the right, + being careful of the end of the text + */ + if ( TxtWordBounds( textP, textLen, leftPos, &wordStart, &wordEnd ) || + ((leftPos != insPtPos) && (insPtPos < textLen) && + TxtWordBounds( textP, textLen, insPtPos, &wordStart, &wordEnd )) ) + { + if ( 0 == wordStart ) + firstAddress = true; + } + } + else + { + firstAddress = true; + } + } + else + { + firstAddress = true; + } + + if ( firstAddress ) + { + formatH = DmGetResource( strRsc, mailLookupFormatStrID ); + } + else + { + formatH = DmGetResource( strRsc, mailAddlLookupFormatStrID ); + } + buttonH = DmGetResource (strRsc, phoneLookupAddStrID); + titleH = DmGetResource (strRsc, titleStrID); + + ErrNonFatalDisplayIf(!formatH, "null resource"); + ErrNonFatalDisplayIf(!buttonH, "null resource"); + ErrNonFatalDisplayIf(!titleH, "null resource"); + + params.title = MemHandleLock (titleH); + params.pasteButtonText = MemHandleLock(buttonH); + params.formatStringP = MemHandleLock(formatH); + params.field1 = addrLookupSortField; + params.field2 = addrLookupEmail; + params.field2Optional = false; + params.userShouldInteract = true; + + PhoneNumberLookupCustom (fld, ¶ms, true); + + MemHandleUnlock(titleH); + MemHandleUnlock(buttonH); + MemHandleUnlock(formatH); + DmReleaseResource(titleH); + DmReleaseResource(buttonH); + DmReleaseResource(formatH); +} diff --git a/handera-sdk-105/examples/Mail/Src/MailLookup.h b/handera-sdk-105/examples/Mail/Src/MailLookup.h new file mode 100644 index 0000000..df447e3 --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/MailLookup.h @@ -0,0 +1,19 @@ +/****************************************************************************** + * + * Copyright (c) 1996-1999 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MailLookup.h + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This file defines the email address lookup structures and functions of + * the mail application. + * + * History: + * June 26, 1996 Created by Art Lamb + * + *****************************************************************************/ + +extern void AddressLookup (FieldPtr fld); diff --git a/handera-sdk-105/examples/Mail/Src/MailMessage.c b/handera-sdk-105/examples/Mail/Src/MailMessage.c new file mode 100644 index 0000000..528c817 --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/MailMessage.c @@ -0,0 +1,2443 @@ +/****************************************************************************** + * + * Copyright (c) 1996-2000 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MailMessage.c + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This is the Mail application's main module. + * + * History: + * June 19, 1996 Created by Art Lamb + * + *****************************************************************************/ + +#include + +#include + +#include "Mail.h" + + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define tabChrWidth 20 + +#define maxCopyLength 1000 + + +/*********************************************************************** + * + * Internal Structutes + * + ***********************************************************************/ + +typedef struct { + UInt16 tabStop; + UInt16 fieldTextPos; + Char * fieldText; + MsgFieldType fieldType; + MsgSelectFieldType selectStartField; + MsgSelectFieldType selectEndField; + UInt8 reserved1; + UInt16 selectStartPos; + UInt16 selectEndPos; + RectangleType bounds; + MailDBRecordType record; + MemHandle recordH; + Char dateStr [timeStringLength + timeStringLength + 1]; + Char toFriendlyName [maxFriendlyNameLen]; + Char fromFriendlyName [maxFriendlyNameLen]; + UInt8 reserved2; +} MessegeInfoType; + +typedef MessegeInfoType * MessegeInfoPtr; + + +/*********************************************************************** + * + * Internal Routines + * + ***********************************************************************/ + +static Char * MsgGetFieldPtr (MessegeInfoPtr msg); + + +/*********************************************************************** + * + * FUNCTION: MsgInit + * + * DESCRIPTION: This routine initialize the structure used to draw and + * scroll a mesage. + * + * PARAMETERS: msg - structure to initilize + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * + ***********************************************************************/ +static void MsgInit (MessegeInfoPtr msg, MsgFieldType fieldType, + UInt16 fieldTextPos) +{ + UInt16 len; + UInt16 objIndex; + FormPtr frm; + FontID oldFont; + UInt16 tabStop; + int i; + static UInt16 labelIDs[] = { toStrId, fromStrId, subjectStrId, ccStrId, dateStrId }; + + // Get the tab stop for the start of the header text. + // DOLATER kwk - figure out if it's safe to use static labelIDs here, + // since they rely on globals. + oldFont = FntSetFont (MessageFont); + tabStop = 0; + + for (i = 0; i < sizeof (labelIDs) / sizeof (labelIDs[0]); i += 1) + { + MemHandle resH; + + resH = DmGetResource (strRsc, labelIDs[i]); + if (resH != 0) + { + Char * ptr; + Int16 width; + + ptr = MemHandleLock (resH); + width = FntCharsWidth (ptr, StrLen (ptr)); + if (tabStop < width) + { + tabStop = width; + } + MemHandleUnlock (resH); + DmReleaseResource (resH); + } + } + + msg->tabStop = tabStop; + FntSetFont (oldFont); + + // Get the bounds of the message. + frm = FrmGetActiveForm (); + objIndex = FrmGetObjectIndex (frm, MessageGadget); + FrmGetObjectBounds (frm, objIndex, &msg->bounds); + + // Get the current record + MailGetRecord (MailDB, CurrentRecord, &msg->record, &msg->recordH); + + // Get the friendly mame of the recipent and the sender of the message. + *msg->toFriendlyName = 0; + if ((msg->record.sentTo) && StrChr (msg->record.sentTo, '(')) + { + MailParseAddress (msg->record.sentTo, true, msg->toFriendlyName, + maxFriendlyNameLen); + } + + *msg->fromFriendlyName = 0; + if ((msg->record.from) && StrChr (msg->record.from, '(')) + { + MailParseAddress (msg->record.from, true, msg->fromFriendlyName, + maxFriendlyNameLen); + } + + + msg->fieldTextPos = fieldTextPos; + msg->fieldType = fieldType; + + msg->fieldText = MsgGetFieldPtr (msg); + + msg->selectStartField = MessageSelectStartField; + msg->selectEndField = MessageSelectEndField; + msg->selectStartPos = MessageSelectStartPos; + msg->selectEndPos = MessageSelectEndPos; + + if (DateToInt (msg->record.date)) + { + // Format the date and time. + DateToAscii (msg->record.date.month, + msg->record.date.day, + (msg->record.date.year+firstYear) % 100, + DateFormat, + msg->dateStr); + + len = StrLen (msg->dateStr); + msg->dateStr [len++] = spaceChr; + + TimeToAscii (msg->record.time.hours, + msg->record.time.minutes, + TimeFormat, + &msg->dateStr[len]); + } + else + { + *msg->dateStr = 0; + } +} + + + +/*********************************************************************** + * + * FUNCTION: MsgSearch + * + * DESCRIPTION: This routine searchs the fields of the mail message + * that are displayable in the Message View. + * + * PARAMETERS: strToFind - string to find + * fieldP - returned: field the match occurred in + * posP - starting character position of the match + * + * RETURNED: true if a match was found + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/27/96 Initial Revision + * + ***********************************************************************/ +Boolean MsgSearch (MailDBRecordPtr recordP, Char * strToFind, + UInt16 * fieldNumP, UInt16 * posP, UInt16 * matchLengthP) +{ + UInt32 pos; + UInt16 matchLength; + UInt16 fieldType; + Char * ptr; + Char friendlyName [maxFriendlyNameLen]; + + + for (fieldType = msgFieldSentTo; fieldType <= msgFieldBody; fieldType++) + { + switch (fieldType) + { + case msgFieldSentTo: + if ((recordP->sentTo) && StrChr (recordP->sentTo, '(' )) + { + MailParseAddress (recordP->sentTo, true, friendlyName, maxFriendlyNameLen); + ptr = friendlyName; + } + else + ptr = recordP->sentTo; + break; + + case msgFieldTo: + ptr = recordP->to; + break; + + case msgFieldFrom: + ptr = recordP->from; + break; + + case msgFieldSubject: + ptr = recordP->subject; + break; + + case msgFieldCC: + ptr = recordP->cc; + break; + + case msgFieldBody: + ptr = recordP->body; + break; + + default: + ptr = NULL; + } + + if (ptr && *ptr) + { + if (TxtFindString (ptr, strToFind, &pos, &matchLength)) + { + *fieldNumP = fieldType; + *posP = pos; + /* CS2 (24659, 25166, 44807): pass along selection range */ + *matchLengthP = matchLength; + return (true); + } + } + } + return (false); +} + + +/*********************************************************************** + * + * FUNCTION: MsgIsHeaderField + * + * DESCRIPTION: Returns true if the mail field passed is a header field. + * + * PARAMETERS: fieldType - type a a mail record field. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * + ***********************************************************************/ +static Boolean MsgIsHeaderField (MsgFieldType fieldType) +{ + switch (fieldType) + { + case msgFieldSentTo: + case msgFieldTo: + case msgFieldFrom: + case msgFieldSubject: + case msgFieldCC: + case msgFieldDate: + return (true); + break; + } + return (false); +} + + +/*********************************************************************** + * + * FUNCTION: MsgGetHeaderLabel + * + * DESCRIPTION: Returns a pointer to a header line's label. + * + * PARAMETERS: fieldType - type a a mail record field. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * + ***********************************************************************/ +static MemHandle MsgGetHeaderLabel (MsgFieldType fieldType, MailAddressingType addressing) +{ + UInt16 id; + + switch (fieldType) + { + case msgFieldSentTo: + switch (addressing) + { + case sentTo: + id = toStrId; + break; + case sentCC: + id = ccStrId; + break; + case sentBCC: + id = bccStrId; + break; + } + break; + + + case msgFieldTo: + id = toStrId; + break; + + case msgFieldFrom: + id = fromStrId; + break; + + case msgFieldSubject: + id = subjectStrId; + break; + + case msgFieldCC: + id = ccStrId; + break; + + case msgFieldDate: + id = dateStrId; + break; + + default: + return (0); + + } + + return (DmGetResource (strRsc, id)); +} + + +/*********************************************************************** + * + * FUNCTION: MsgGetFieldPtr + * + * DESCRIPTION: This routine returns a pointer to the specified field + * of the record passed. + * + * PARAMETERS: fieldType - type a a mail record field. + * repordP - pointer to a mail record. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * + ***********************************************************************/ +static Char * MsgGetFieldPtr (MessegeInfoPtr msg) +{ + switch (msg->fieldType) + { + case msgFieldSentTo: + if (*msg->toFriendlyName) + return (msg->toFriendlyName); + else + return (msg->record.sentTo); + + case msgFieldTo: + return (msg->record.to); + + case msgFieldFrom: + if (ShowFullHeader) + return (msg->record.from); + else if (*msg->fromFriendlyName) + return (msg->fromFriendlyName); + else + return (msg->record.from); + + case msgFieldSubject: + return (msg->record.subject); + + case msgFieldCC: + return (msg->record.cc); + + case msgFieldBody: + return (msg->record.body); + + case msgFieldDate: + return (msg->dateStr); + } + return (NULL); +} + + +/*********************************************************************** + * + * FUNCTION: MsgNextField + * + * DESCRIPTION: This routine the previous field of a message. + * + * PARAMETERS: msg - used to draw and scroll a mesage. + * + * RETURNED: false if there is no next field + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/21/96 Initial Revision + * + ***********************************************************************/ +static Boolean MsgPreviousField (MessegeInfoPtr msg) +{ + if (ShowFullHeader) + { + switch (msg->fieldType) + { + case msgFieldTo: + case msgFieldSentTo: + msg->fieldText = NULL; + return (false); + + case msgFieldFrom: + msg->fieldType = msgFieldTo; + msg->fieldText = msg->record.to; + break; + + case msgFieldCC: + msg->fieldType = msgFieldFrom; + msg->fieldText = msg->record.from; + break; + + case msgFieldSubject: + msg->fieldType = msgFieldCC; + msg->fieldText = msg->record.cc; + break; + + case msgFieldDate: + msg->fieldType = msgFieldSubject; + msg->fieldText = msg->record.subject; + break; + + case msgFieldBlankLine: + msg->fieldType = msgFieldDate; + msg->fieldText = msg->dateStr; + break; + + case msgFieldBody: + msg->fieldType = msgFieldBlankLine; + msg->fieldText = NULL; + break; + } + } +/* + switch (msg->fieldType) + { + case msgFieldTo: + case msgFieldSentTo: + msg->fieldText = NULL; + return (false); + + case msgFieldFrom: + msg->fieldType = msgFieldTo; + msg->fieldText = msg->record.to; + break; + + case msgFieldSubject: + msg->fieldType = msgFieldFrom; + msg->fieldText = msg->record.from; + break; + + case msgFieldCC: + msg->fieldType = msgFieldSubject; + msg->fieldText = msg->record.subject; + break; + + case msgFieldDate: + msg->fieldType = msgFieldCC; + msg->fieldText = msg->record.cc; + break; + + case msgFieldBlankLine: + msg->fieldType = msgFieldDate; + msg->fieldText = msg->dateStr; + break; + + case msgFieldBody: + msg->fieldType = msgFieldBlankLine; + msg->fieldText = NULL; + break; + } + } +*/ + + else + { + switch (msg->fieldType) + { + case msgFieldTo: + case msgFieldSentTo: + return (false); + + case msgFieldFrom: + case msgFieldSubject: + case msgFieldCC: + case msgFieldDate: + msg->fieldType = msgFieldSentTo; + if (*msg->toFriendlyName) + msg->fieldText = msg->toFriendlyName; + else + msg->fieldText = msg->record.sentTo; + break; + + case msgFieldBlankLine: + msg->fieldType = msgFieldFrom; + if (*msg->fromFriendlyName) + msg->fieldText = msg->fromFriendlyName; + else + msg->fieldText = msg->record.from; + break; + + case msgFieldBody: + msg->fieldType = msgFieldBlankLine; + msg->fieldText = NULL; + break; + } + } + + if (msg->fieldText) + msg->fieldTextPos = StrLen (msg->fieldText); + else + msg->fieldTextPos = 0; + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: MsgNextField + * + * DESCRIPTION: This routine the next field of a message. + * + * PARAMETERS: msg - used to draw and scroll a mesage. + * + * RETURNED: false if there is no next field + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * MGolden 7/11/97 Added the subject view to the Int16 header + * + ***********************************************************************/ +static Boolean MsgNextField (MessegeInfoPtr msg) +{ + if (ShowFullHeader) + { + switch (msg->fieldType) + { + case msgFieldTo: + case msgFieldSentTo: + msg->fieldType = msgFieldFrom; + msg->fieldText = msg->record.from; + break; + + case msgFieldFrom: + msg->fieldType = msgFieldCC; + msg->fieldText = msg->record.cc; + break; + + case msgFieldCC: + msg->fieldType = msgFieldSubject; + msg->fieldText = msg->record.subject; + break; + + case msgFieldSubject: + msg->fieldType = msgFieldDate; + msg->fieldText = msg->dateStr; + break; + + case msgFieldDate: + msg->fieldType = msgFieldBlankLine; + msg->fieldText = NULL; + break; + + case msgFieldBlankLine: + msg->fieldType = msgFieldBody; + msg->fieldText = msg->record.body; + break; + + case msgFieldBody: + return (false); + } + } + + else + { + switch (msg->fieldType) + { + case msgFieldTo: + case msgFieldSentTo: + msg->fieldType = msgFieldFrom; + if (*msg->fromFriendlyName) + msg->fieldText = msg->fromFriendlyName; + else + msg->fieldText = msg->record.from; + break; + +//mgmg new add the subject field to the Int16 header... + case msgFieldFrom: + msg->fieldType = msgFieldSubject; + msg->fieldText = msg->record.subject; + break; + + + case msgFieldSubject: + case msgFieldCC: + case msgFieldDate: + msg->fieldType = msgFieldBlankLine; + msg->fieldText = NULL; + break; + + case msgFieldBlankLine: + msg->fieldType = msgFieldBody; + msg->fieldText = msg->record.body; + break; + + case msgFieldBody: + return (false); + } + } + + msg->fieldTextPos = 0; + + return (true); +} + + +/*********************************************************************** + * + * FUNCTION: MsgSelectFieldVisible + * + * DESCRIPTION: This routine returns true if the selection field is + * visible in the current message line. + * + * PARAMETERS: msg - used to draw and scroll a mesage. + * selectField - label of field of message + * + * RETURNED: true if selection field is visible + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/28/96 Initial Revision + * + ***********************************************************************/ +static Boolean MsgSelectFieldVisible (MessegeInfoPtr msg, + MsgSelectFieldType selectField) +{ + UInt16 pos; + MsgFieldType fieldType; + + if (msg->selectStartField > selectField || + msg->selectEndField < selectField) + return (false); + + + fieldType = msg->fieldType; + pos = msg->fieldTextPos; + + switch (selectField) + { + case msgSelectSentToLabel: + return (fieldType == msgFieldSentTo && pos == 0); + + case msgSelectSentTo: + return (fieldType == msgFieldSentTo); + + case msgSelectToLabel: + return (fieldType == msgFieldTo && pos == 0); + + case msgSelectTo: + return (fieldType == msgFieldTo); + + case msgSelectFromLabel: + return (fieldType == msgFieldFrom && pos == 0); + + case msgSelectFrom: + return (fieldType == msgFieldFrom); + + case msgSelectSubjectLabel: + return (fieldType == msgFieldSubject && pos == 0); + + case msgSelectSubject: + return (fieldType == msgFieldSubject); + + case msgSelectCC: + return (fieldType == msgFieldCC && ShowFullHeader); + + case msgSelectCCLabel: + return (fieldType == msgFieldCC && pos == 0 && ShowFullHeader); + + case msgSelectDate: + return (fieldType == msgFieldDate && ShowFullHeader); + + case msgSelectDateLabel: + return (fieldType == msgFieldDate && pos == 0 && ShowFullHeader); + + case msgSelectBlankLine: + return (fieldType == msgFieldBlankLine); + + case msgSelectBody: + return (fieldType == msgFieldBody); + + } + return (false); +} + + +/*********************************************************************** + * + * FUNCTION: MsgWordWrap + * + * DESCRIPTION: Given a string, determine the number of characters that + * can be displayed within the specified width. + * + * PARAMETERS: msg - structure contain info for word wrapping + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * + ***********************************************************************/ +static UInt16 MsgWordWrap (MessegeInfoPtr msg) +{ + UInt16 width; + UInt16 length = 0; + Char * ptr; + Boolean header; + + + // Leave room for the field description (ex: "To:") if the field + // has a description. + header = MsgIsHeaderField (msg->fieldType); + if (header) + { + width = msg->bounds.extent.x - msg->tabStop; + } + else + width = msg->bounds.extent.x; + + ptr = MsgGetFieldPtr (msg); + + if (ptr) + { + ptr += msg->fieldTextPos; + length = FntWordWrap (ptr, width); + } + + + +/* + // If the field is a header and we didn't wrap on a space of linefeed + // character then wrap on the last address punctuation character. + if (header && length) + { + count = 0; + ptr += length - 1; + if (*(ptr+1) != nullChr && *ptr != spaceChr && *ptr != linefeedChr) + { + while (count < length) + { + // Wrap after right paren. + if (*ptr == ')') + { + length -= count; + break; + } + // Wrap before left paren, @, and period. + else if (*ptr == '(' || *ptr == '@' || *ptr == periodChr) + { + if (length > count + 1) + length -= count + 1; + break; + } + count++; + ptr--; + } + } + } +*/ + return (length); +} + + +/*********************************************************************** + * + * FUNCTION: MsgIsLableField + * + * DESCRIPTION: Returns true if the field passed is a label field. + * + * PARAMETERS: selectField - masseage label a field + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * + ***********************************************************************/ +static Boolean MsgIsLableField (MsgSelectFieldType selectField) +{ + switch (selectField) + { + case msgSelectSentToLabel: + case msgSelectToLabel: + case msgSelectFromLabel: + case msgSelectSubjectLabel: + case msgSelectCCLabel: + case msgSelectDateLabel: + return (true); + } + return (false); +} + + +/*********************************************************************** + * + * FUNCTION: InvertCharsRange + * + * DESCRIPTION: Invert specified characer range on the specified line. + * This rountine performs the actual inverting. + * + * PARAMETERS: fld pointer to a FieldType structure. + * lineNum line number + * startPos character position of start of range + * endPos character position of end of range. + * + * RETURNED: nothing. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/28/96 Initial Revision + * + ***********************************************************************/ +static void MsgInvertCharsRange (MessegeInfoPtr msg, MsgSelectFieldType selectField, + UInt16 lineNumber, UInt16 startPos, UInt16 endPos) +{ + UInt16 length; + Int16 left; + Int16 width; + Char * ptr; + MemHandle resH; + Boolean label; + RectangleType r; + + + label = MsgIsLableField (selectField); + + if (label) + { + resH = MsgGetHeaderLabel (msg->fieldType, + (MailAddressingType) msg->record.flags.addressing); + ptr = MemHandleLock (resH); + + length = FntLineWidth (ptr, StrLen(ptr)); + left = msg->bounds.topLeft.x + + (msg->tabStop - length) + + FntLineWidth (ptr, startPos); + } + + else if (msg->fieldText) + { + ptr = msg->fieldText; + + left = msg->bounds.topLeft.x + + FntLineWidth (&ptr[msg->fieldTextPos], startPos - msg->fieldTextPos); + + if (MsgIsHeaderField (msg->fieldType)) + left += msg->tabStop; + } + else + return; + + + width = FntLineWidth (&ptr[startPos], endPos - startPos); + + + r.topLeft.x = left; + r.extent.x = width; + + r.extent.y = FntLineHeight (); + r.topLeft.y = msg->bounds.topLeft.y + (lineNumber * FntLineHeight ()); + + if (r.topLeft.x + r.extent.x > msg->bounds.topLeft.x + msg->bounds.extent.x) + r.extent.x = msg->bounds.extent.x - (r.topLeft.x - msg->bounds.topLeft.x); + +/* CS2 (23430): use swap mode, not invert, for selection + WinInvertRectangle (&r, 0); +*/ + + WinPushDrawState(); + WinSetDrawMode( winSwap ); + WinPaintRectangle( &r, 0 ); + WinPopDrawState(); + + if (label) + { + MemHandleUnlock (resH); + DmReleaseResource (resH); + } +} + + +/*********************************************************************** + * + * FUNCTION: MsgInvertSelection + * + * DESCRIPTION: Invert the current selection. + * + * PARAMETERS: nothing + * + * RETURNED: nothing. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/28/96 Initial Revision + * + ***********************************************************************/ +static void MsgInvertSelection (MessegeInfoPtr msg) +{ + UInt16 length; + UInt16 lineNumber; + UInt16 numLines; + UInt16 startPos; + UInt16 endPos; + Char * ptr; + MemHandle resH; + MsgSelectFieldType selectField; + + if (msg->selectStartField == msgSelectNone) + return; + + lineNumber = 0; + numLines = msg->bounds.extent.y / FntLineHeight (); + + while (lineNumber < numLines) + { + length = MsgWordWrap (msg); + if (length) + { + for (selectField = msg->selectStartField; + selectField <= msg->selectEndField; selectField++) + { + if (MsgSelectFieldVisible (msg, selectField)) + { + if (MsgIsLableField (selectField)) + { + if (selectField == msg->selectStartField) + startPos = msg->selectStartPos; + else + startPos = 0; + + if (selectField == msg->selectEndField) + endPos = msg->selectEndPos; + else + { + resH = MsgGetHeaderLabel (msg->fieldType, + (MailAddressingType) msg->record.flags.addressing); + ptr = MemHandleLock (resH); + endPos = StrLen (ptr); + MemHandleUnlock (resH); + DmReleaseResource (resH); + } + } + + else + { + if (selectField == msg->selectStartField) + { + if (msg->selectStartPos < msg->fieldTextPos + length) + startPos = max (msg->selectStartPos, msg->fieldTextPos); + else + continue; + } + else + startPos = msg->fieldTextPos; + + + if (selectField == msg->selectEndField) + { + if (msg->selectEndPos >= msg->fieldTextPos) + endPos = min (msg->selectEndPos, msg->fieldTextPos + length); + else + continue; + } + else + endPos = msg->fieldTextPos + length; + } + + + MsgInvertCharsRange (msg, selectField, lineNumber, startPos, endPos); + } + } + + msg->fieldTextPos += length; + lineNumber++; + } + else + { + if (msg->fieldType == msgFieldBlankLine) + lineNumber++; + if (! MsgNextField (msg)) + break; + } + } +} + + + +/*********************************************************************** + * + * FUNCTION: MsgDrawLine + * + * DESCRIPTION: This routine draws a line of the message. + * + * PARAMETERS: msg - structure contain info for drawing + * charsToDraw - the number of characters to draw + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * + ***********************************************************************/ +static void MsgDrawLine (MessegeInfoPtr msg, UInt16 charsToDraw, + UInt16 lineNumber) +{ + UInt16 len; + UInt16 count; + UInt16 charsDrawn; + Int16 x, y; + Int16 drawX; + Char * ptr; + Boolean header; + + // Calculate the draw position of the line. + x = msg->bounds.topLeft.x; + y = msg->bounds.topLeft.y + (lineNumber * FntLineHeight ()); + + // If the line is the start of of the header draw the header label. + header = MsgIsHeaderField (msg->fieldType); + if (header) + { + if (msg->fieldTextPos == 0) + { + ptr = MemHandleLock (MsgGetHeaderLabel (msg->fieldType, + (MailAddressingType) msg->record.flags.addressing)); + len = StrLen (ptr); + drawX = x +( Int16)msg->tabStop - (Int16)FntCharsWidth (ptr, len); + WinDrawChars (ptr, len, drawX, y); + MemPtrUnlock (ptr); + } + x += msg->tabStop; + } + + // Get a pointer to the start of the text to draw. + ptr = MsgGetFieldPtr (msg); + ptr += msg->fieldTextPos; + + // Don't draw the linefeedChr character. + if ((charsToDraw) && ptr[charsToDraw-1] == linefeedChr) + charsToDraw--; + + // Don't draw trailing spaceChrs. + while (charsToDraw && ptr[charsToDraw-1] == spaceChr) + charsToDraw--; + + // Draw the text. + count = 0; + charsDrawn = 0; + while (true) + { + // Count until we reach a tab character. + while ((count < charsToDraw) && (ptr[count] != tabChr)) + count++; + + // Draw the characters until/between the tab characters. + WinDrawChars (&ptr[charsDrawn], count-charsDrawn, x, y); + if (count >= charsToDraw) break; + + // Move the draw position past the tab. + x += FntLineWidth (&ptr[charsDrawn], count-charsDrawn); + x += tabChrWidth - ((x - msg->bounds.topLeft.x) % tabChrWidth); + + // Skip over the tab. + count++; + charsDrawn = count; + } +} + + + +/*********************************************************************** + * + * FUNCTION: MsgDraw + * + * DESCRIPTION: This routine draws an mail message. + * + * PARAMETERS: msg - structure contain info for drawing. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * + ***********************************************************************/ +void MsgDraw (void) +{ + UInt16 length; + UInt16 lineNumber; + UInt16 linesToDraw; + FontID currFont; + MessegeInfoType msg; + Boolean isHeader; + + currFont = FntSetFont (MessageFont); + + MsgInit (&msg, MessageTopField, MessageScrollPos); + + lineNumber = 0; + linesToDraw = msg.bounds.extent.y / FntLineHeight (); + + while (lineNumber < linesToDraw) + { + isHeader = false; + //mgmg change this to draw the empty header if needed... + length = MsgWordWrap (&msg); + if (length) + { + MsgDrawLine (&msg, length, lineNumber); + msg.fieldTextPos += length; + lineNumber++; + } + else if (msg.fieldType == msgFieldBlankLine) + { + lineNumber++; + if (! MsgNextField (&msg)) + break; + } + else if (!MsgNextField (&msg)) + break; + } + + MemHandleUnlock (msg.recordH); + + + MsgInit (&msg, MessageTopField, MessageScrollPos); + MsgInvertSelection (&msg); + MemHandleUnlock (msg.recordH); + + FntSetFont (currFont); +} + + +/*********************************************************************** + * + * FUNCTION: MsgErase + * + * DESCRIPTION: This routine erase the current mail message. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/19/96 Initial Revision + * + ***********************************************************************/ +void MsgErase (void) +{ + UInt16 objIndex; + FormPtr frm; + RectangleType bounds; + + frm = FrmGetActiveForm (); + objIndex = FrmGetObjectIndex (frm, MessageGadget); + FrmGetObjectBounds (frm, objIndex, &bounds); + WinEraseRectangle (&bounds, 0); +} + + +/*********************************************************************** + * + * FUNCTION: MsgGetFieldHeight + * + * DESCRIPTION: This routine returns the height of a format message + * field. + * + * PARAMETERS: fld - pointer to a FieldType structure. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/20/96 Initial Revision + * + ***********************************************************************/ +static UInt16 MsgGetFieldHeight (MessegeInfoPtr msg) +{ + UInt16 length; + UInt16 lines; + + if (msg->fieldType == msgFieldBlankLine) + return (1); + + lines = 0; + length = 0; + msg->fieldTextPos = 0; + + do + { + length += MsgWordWrap (msg); + msg->fieldTextPos = length; + lines++; + } + while (msg->fieldText[length]); + + // If the text end with a linefeed add one to the height. + if (length && msg->fieldText[length-1] == linefeedChr) + lines++; + + return (lines); +} + + +/*********************************************************************** + * + * FUNCTION: MsgGetScrollValues + * + * DESCRIPTION: This routine returns the values necessary to update a + * scroll bar. + * + * PARAMETERS: fld - pointer to a FieldType structure. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/20/96 Initial Revision + * + ***********************************************************************/ +/* +void MsgGetScrollValues (UInt16 * textHeightP, UInt16 * pageHeightP) +{ + UInt16 lines = 0; + FontID currFont; + MessegeInfoType msg; + + currFont = FntSetFont (MessageFont); + + MsgInit (&msg, msgFieldTo, 0); + + while (true) + { + lines += MsgGetFieldHeight (&msg); + + if (! MsgNextField (&msg)) + break; + } + + MemHandleUnlock (msg.recordH); + FntSetFont (currFont); + + *textHeightP = lines; + *pageHeightP = msg.bounds.extent.y / FntLineHeight ();; +} +*/ + + +/*********************************************************************** + * + * FUNCTION: MsgGetScrollValues + * + * DESCRIPTION: This routine returns the values necessary to update a + * scroll bar. + * + * PARAMETERS: fld - pointer to a FieldType structure. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/20/96 Initial Revision + * + ***********************************************************************/ +void MsgGetScrollValues (UInt16 * textHeightP, UInt16 * pageHeightP, UInt16 * topLineP) +{ + UInt16 length; + UInt16 lines = 0; + UInt16 topLine = 0; + FontID currFont; + MsgFieldType fieldType; + MessegeInfoType msg; + + currFont = FntSetFont (MessageFont); + + if (ShowFullHeader) + fieldType = msgFieldTo; + else + fieldType = msgFieldSentTo; + + MsgInit (&msg, fieldType, 0); + + while (true) + { + if (msg.fieldType == MessageTopField) + topLine = lines; + + if (msg.fieldType == msgFieldBlankLine) + lines++; + else + { + length = 0; + msg.fieldTextPos = 0; + + do + { + length = MsgWordWrap (&msg); + + if (msg.fieldType == MessageTopField) + { + if (msg.fieldTextPos < MessageScrollPos && + msg.fieldTextPos + length > MessageScrollPos) + { + MessageScrollPos = msg.fieldTextPos; + topLine = lines; + } + else if (msg.fieldTextPos + length == MessageScrollPos) + //mgmg + //topLine = lines; + topLine = lines; + } + + if (length) + { + msg.fieldTextPos += length; + lines++; + } + } + while (msg.fieldText[msg.fieldTextPos]); + + // If the text end with a linefeed add one to the height. + if (length && msg.fieldText[length-1] == linefeedChr) + lines++; + } + + if (! MsgNextField (&msg)) + break; + } + + MemHandleUnlock (msg.recordH); + + *topLineP = topLine; + *textHeightP = lines; + *pageHeightP = msg.bounds.extent.y / FntLineHeight ();; + + FntSetFont (currFont); +} + + +/*********************************************************************** + * + * FUNCTION: MsgScrollUpNLines + * + * DESCRIPTION: This routine scrolls a field of the message winUp by the + * number of lines specified. + * + * PARAMETERS: msg structure contain message info + * linesToScroll number of lines to scroll. + * + * RETURNED: nothing. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 11/1/96 Initial Revision + * + ***********************************************************************/ +static UInt16 MsgScrollUpNLines (MessegeInfoPtr msg, UInt16 linesToScroll) +{ + UInt16 width; + UInt16 lineCount = 0; + + if (msg->fieldText && msg->fieldTextPos) + { + if (MsgIsHeaderField (msg->fieldType)) + width = msg->bounds.extent.x - msg->tabStop; + else + width = msg->bounds.extent.x; + + lineCount = linesToScroll; + FntWordWrapReverseNLines (msg->fieldText, width, + &lineCount, &msg->fieldTextPos); + } + + if (msg->fieldType == msgFieldBlankLine && linesToScroll > 1) + lineCount = 1; + + return (lineCount); +} + + +/*********************************************************************** + * + * FUNCTION: MsgScroll + * + * DESCRIPTION: This routine scrolls the message view by the number of + * lines specified. + * + * PARAMETERS: direction - winUp or dowm + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 6/20/96 Initial Revision + * + ***********************************************************************/ +void MsgScroll (Int16 linesToScroll, WinDirectionType direction) +{ + UInt16 length; + UInt16 linesScrolled; + FontID currFont; + MessegeInfoType msg; + + currFont = FntSetFont (MessageFont); + MsgInit (&msg, MessageTopField, MessageScrollPos); + + if (direction == winUp) + { + while (true) + { + linesScrolled = MsgScrollUpNLines (&msg, linesToScroll); + if (linesScrolled == linesToScroll) + break; + linesToScroll -= linesScrolled; + + if (! MsgPreviousField (&msg)) + break; + } + } + + + else if (direction == winDown) + { + while (linesToScroll) + { + length = MsgWordWrap (&msg); + if (length) + { + msg.fieldTextPos += length; + linesToScroll--; + } + else + { + if (msg.fieldType == msgFieldBlankLine) + linesToScroll--; + if (! MsgNextField (&msg)) + break; + } + } + + // If we at the end of the current field move to the next field so that + // the field position and field top of the top line will be correct. + if (length && msg.fieldText[msg.fieldTextPos] == 0) + MsgNextField (&msg); + } + + MemHandleUnlock (msg.recordH); + FntSetFont (currFont); + + MessageScrollPos = msg.fieldTextPos; + MessageTopField = msg.fieldType; + + // DOLATER ??? - Optimize redraw + WinEraseRectangle (&msg.bounds, 0); + MsgDraw (); +} + + +/*********************************************************************** + * + * FUNCTION: MsgUpdateHighlight + * + * DESCRIPTION: Adjust the current highlighted region to include or exclude + * the specified range of characters. + * + * PARAMETERS: msg - structure contain message info + * startPos character position of start of range + * endPos character position of end of range. + * + * RETURNED: nothing. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/29/96 Initial Revision + * + ***********************************************************************/ +static void MsgUpdateHighlight (MessegeInfoPtr msg, + MsgSelectFieldType startField, UInt16 startPos, + MsgSelectFieldType endField, UInt16 endPos) +{ + MsgSelectFieldType invertStartField; + MsgSelectFieldType invertEndField; + UInt16 invertStartPos; + UInt16 invertEndPos; + + + // No current selection? + if (msg->selectStartField == msg->selectEndField && + msg->selectStartPos == msg->selectEndPos) + { + invertStartField = startField; + invertEndField = endField; + invertStartPos = startPos; + invertEndPos = endPos; + } + + // Add to the end of the selection. + else if (msg->selectStartField == startField && + msg->selectStartPos == startPos) + { + if (msg->selectEndField < endField) + { + invertStartField = msg->selectEndField; + invertStartPos = msg->selectEndPos; + invertEndField = endField; + invertEndPos = endPos; + } + else if (msg->selectEndField > endField) + { + invertStartField = endField; + invertStartPos = endPos; + invertEndField = msg->selectEndField; + invertEndPos = msg->selectEndPos; + } + else + { + invertStartField = msg->selectEndField; + invertEndField = msg->selectEndField; + if (msg->selectEndPos < endPos) + { + invertStartPos = msg->selectEndPos; + invertEndPos = endPos; + } + else + { + invertStartPos = endPos; + invertEndPos = msg->selectEndPos; + } + } + } + + // Add to the start of the selection. + else if (msg->selectEndField == endField && + msg->selectEndPos == endPos) + { + if (msg->selectStartField < startField) + { + invertStartField = msg->selectStartField; + invertStartPos = msg->selectStartPos; + invertEndField = startField; + invertEndPos = startPos; + } + else if (msg->selectStartField > startField) + { + invertStartField = startField; + invertStartPos = startPos; + invertEndField = msg->selectStartField; + invertEndPos = msg->selectStartPos; + } + else + { + invertStartField = msg->selectStartField; + invertEndField = msg->selectStartField; + if (msg->selectStartPos < startPos) + { + invertStartPos = msg->selectStartPos; + invertEndPos = startPos; + } + else + { + invertStartPos = startPos; + invertEndPos = msg->selectStartPos; + } + } + } + + else + { + if (msg->selectStartField < startField) + { + invertStartField = msg->selectStartField; + invertStartPos = msg->selectStartPos; + } + else if (msg->selectStartField > startField) + { + invertStartField = startField; + invertStartPos = startPos; + } + else + { + invertStartField = msg->selectStartField; + invertStartPos = min (msg->selectStartPos, startPos); + } + + if (msg->selectEndField < endField) + { + invertEndField = endField; + invertEndPos = endPos; + } + else if (msg->selectEndField > endField) + { + invertEndField = msg->selectEndField; + invertEndPos = msg->selectEndPos; + } + else + { + invertEndField = msg->selectEndField; + invertEndPos = max (msg->selectEndPos, endPos); + } + } + + msg->selectStartField = invertStartField; + msg->selectStartPos = invertStartPos; + msg->selectEndField = invertEndField; + msg->selectEndPos = invertEndPos; + + MsgInvertSelection (msg); + + msg->selectStartField = startField; + msg->selectStartPos = startPos; + msg->selectEndField = endField; + msg->selectEndPos = endPos; +} + + +/*********************************************************************** + * + * FUNCTION: MsgSetSelection + * + * DESCRIPTION: This + * + * PARAMETERS: + * + * RETURNED: nothing. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/28/96 Initial Revision + * + ***********************************************************************/ +static void MsgSetSelection (MessegeInfoPtr msg, + MsgSelectFieldType startField, UInt16 startPos, + MsgSelectFieldType endField, UInt16 endPos) +{ + UInt16 tempPos; + MsgSelectFieldType tempField; + + if (startField == endField && startPos == endPos) + { + MsgInvertSelection (msg); + msg->selectStartField = msgSelectNone; + msg->selectStartPos = 0; + msg->selectEndField = msgSelectNone; + msg->selectEndPos = 0; + } + + else if (startField > endField) + { + tempField = startField; + startField = endField; + endField = tempField; + + tempPos = startPos; + startPos = endPos; + endPos = tempPos; + } + + else if (startField == endField && startPos > endPos) + { + tempPos = startPos; + startPos = endPos; + endPos = tempPos; + } + + MsgUpdateHighlight (msg, startField, startPos, endField, endPos); + + MessageSelectStartField = msg->selectStartField; + MessageSelectEndField = msg->selectEndField; + MessageSelectStartPos = msg->selectStartPos; + MessageSelectEndPos = msg->selectEndPos; +} + + +/*********************************************************************** + * + * FUNCTION: MsgGetPositionOfPoint + * + * DESCRIPTION: Given the position in the pen this routine will + * return the message field and character position + * of the point. + * + * PARAMETERS: msg - structure contain message info + * x, y - pen position + * fieldP - returned: field the pen is in + * posP - returned: character position the pen is on + * r - returned: bounds of character position + * + * RETURNED: nothing. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/28/96 Initial Revision + * + ***********************************************************************/ +static void MsgGetPositionOfPoint (MessegeInfoPtr msg, Int16 x, Int16 y, + MsgSelectFieldType * fldP, UInt16 * posP, RectanglePtr r) +{ + UInt16 length; + UInt16 lineNumber; + UInt16 lines; + UInt16 width; + UInt16 lastWidth; + Int16 xPos; + Int16 yPos; + Char * ptr; + Boolean more; + Boolean heading; + MemHandle resH = 0; + UInt16 chSize; + + + // Find the line the point is on. + y = max (y, msg->bounds.topLeft.y); + y = min (y, msg->bounds.topLeft.y + msg->bounds.extent.y - 1); + yPos = (y - msg->bounds.topLeft.y) / FntLineHeight (); + + lineNumber = 0; + lines = msg->bounds.extent.y / FntLineHeight (); + length = 0; + + while (lineNumber < lines) + { + if (lineNumber >= yPos) + break; + + length = MsgWordWrap (msg); + if (length) + { + msg->fieldTextPos += length; + lineNumber++; + } + + + if ((! length) || (msg->fieldText [msg->fieldTextPos] == 0)) + { + while (true) + { + if (msg->fieldType == msgFieldBlankLine) + { + if (lineNumber >= yPos) + break; + lineNumber++; + } + + more = MsgNextField (msg); + if (! more) + break; + + if (msg->fieldText && *msg->fieldText) + break; + } + if (! more) break; + } + } + + + + // Find the field the point in on. + x = max (x, msg->bounds.topLeft.x); + x = min (x, msg->bounds.topLeft.y + msg->bounds.extent.x - 1); + + heading = MsgIsHeaderField (msg->fieldType); + if (heading && + (msg->fieldTextPos == 0) && + (x - msg->bounds.topLeft.x <= msg->tabStop)) + { + switch (msg->fieldType) + { + case msgFieldSentTo: *fldP = msgSelectSentToLabel; break; + case msgFieldTo: *fldP = msgSelectToLabel; break; + case msgFieldFrom: *fldP = msgSelectFromLabel; break; + case msgFieldSubject: *fldP = msgSelectSubjectLabel; break; + case msgFieldCC: *fldP = msgSelectCCLabel; break; + case msgFieldDate: *fldP = msgSelectDateLabel; break; + } + + resH = MsgGetHeaderLabel (msg->fieldType, + (MailAddressingType) msg->record.flags.addressing); + ptr = MemHandleLock (resH); + length = FntCharsWidth (ptr, StrLen (ptr)); + + x -= (msg->tabStop - length); + if (x < 0) x = 0; + } + + else + { + switch (msg->fieldType) + { + case msgFieldSentTo: *fldP = msgSelectSentTo; break; + case msgFieldTo: *fldP = msgSelectTo; break; + case msgFieldFrom: *fldP = msgSelectFrom; break; + case msgFieldSubject: *fldP = msgSelectSubject; break; + case msgFieldCC: *fldP = msgSelectCC; break; + case msgFieldDate: *fldP = msgSelectDate; break; + case msgFieldBlankLine: *fldP = msgSelectBlankLine; break; + case msgFieldBody: *fldP = msgSelectBody; break; + } + + ptr = msg->fieldText + msg->fieldTextPos; + length = MsgWordWrap (msg); + if (length && ptr[length-1] == linefeedChr) + length--; + + if (heading) + x -= msg->tabStop; + } + + + // Determine the character position of the point. +// if ((! ptr) || (! *ptr)) +// { +// *posP = 0; +// } + + if (! ptr) + *posP = 0; + + else if (! *ptr) + *posP = msg->fieldTextPos; + + else + { + xPos = 0; + width = 0; + lastWidth = 0; + while (xPos < length) + { + chSize = TxtGetNextChar (ptr, xPos, NULL); + width += (ptr[xPos] == tabChr + ? tabChrWidth - (width % tabChrWidth) + : FntCharsWidth (&ptr[xPos], chSize)); + + if (width >= x) + { + if ((x - lastWidth) >= ((width - lastWidth) >> 1)) + xPos += chSize; + break; + } + xPos += chSize; + lastWidth = width; + } +// if (! resH) +// xPos += msg->fieldTextPos; +// *posP = xPos; + *posP = xPos + msg->fieldTextPos; + } + + + // Determine the bounds of the character position. + r->topLeft.x = msg->bounds.topLeft.x; + r->extent.x = msg->bounds.extent.x; + r->topLeft.y = msg->bounds.topLeft.y + (yPos * FntLineHeight()); + r->extent.y = FntLineHeight(); + + if (length) + { + width = 0; + + // Calculate the size of half of the width of the character before + // the insertion point. + if (xPos > 0) + { + chSize = TxtGetPreviousChar (ptr, xPos, NULL); + width = (ptr[xPos - chSize] != tabChr ? (FntCharsWidth (&ptr[xPos - chSize], chSize) + 1) / 2 + : xPos > 1 ? (FntLineWidth (ptr, xPos) - FntLineWidth (ptr, xPos - chSize) + 1) / 2 + : (tabChrWidth + 1) / 2); + + r->topLeft.x += FntLineWidth (ptr, xPos) - width; + } + + // Add half of the width of the character following the insertion point. + chSize = TxtGetNextChar (ptr, xPos, NULL); + width += (ptr[xPos] != tabChr ? FntCharsWidth (&ptr[xPos], chSize) / 2 + : length > 1 ? (FntLineWidth (ptr, xPos + chSize) - FntLineWidth (ptr, xPos)) / 2 + : tabChrWidth / 2); + + r->extent.x = width; + } + + switch (*fldP) + { + case msgSelectSentToLabel: + case msgSelectToLabel: + case msgSelectFromLabel: + case msgSelectSubjectLabel: + case msgSelectCCLabel: + case msgSelectDateLabel: + r->topLeft.x += (msg->tabStop - length); + break; + + case msgSelectSentTo: + case msgSelectTo: + case msgSelectFrom: + case msgSelectSubject: + case msgSelectCC: + case msgSelectDate: + r->topLeft.x += msg->tabStop; + break; + } + + +// WinInvertRectangle (r, 0); + + if (resH) + MemHandleUnlock (resH); +} + + +/*********************************************************************** + * + * FUNCTION: MsgSelect + * + * DESCRIPTION: This is the massage selection routine. + * + * PARAMETERS: x, y - starting pen position + * + * RETURNED: nothing. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/28/96 Initial Revision + * + ***********************************************************************/ +void MsgSelect (Int16 x, Int16 y) +{ + FontID currFont; + UInt16 penPos; + UInt16 anchorPos; + Int16 value; + Int16 min; + Int16 max; + Int16 pageSize; + FormPtr frm; + Boolean penDown; + Boolean update; + ScrollBarPtr bar; + RectangleType r; + MessegeInfoType msg; + MsgSelectFieldType penFld; + MsgSelectFieldType anchorFld; + + currFont = FntSetFont (MessageFont); + + MsgInit (&msg, MessageTopField, MessageScrollPos); + + // Cancel the existing selection + MsgSetSelection (&msg, msgSelectNone, 0, msgSelectNone, 0); + + msg.fieldTextPos = MessageScrollPos; + msg.fieldType = MessageTopField; + msg.fieldText = MsgGetFieldPtr (&msg); + MsgGetPositionOfPoint (&msg, x, y, &anchorFld, &anchorPos, &r); + + msg.fieldTextPos = MessageScrollPos; + msg.fieldType = MessageTopField; + msg.fieldText = MsgGetFieldPtr (&msg); + MsgSetSelection (&msg, anchorFld, anchorPos, anchorFld, anchorPos); + + + frm = FrmGetActiveForm (); + bar = FrmGetObjectPtr (frm, FrmGetObjectIndex (frm, MessageScrollBar)); + + do + { + // Above the message bounds? + if (y < msg.bounds.topLeft.y) + { + SclGetScrollBar (bar, &value, &min, &max, &pageSize); + if (value) + { + MsgScroll (1, winUp); + SclSetScrollBar (bar, value-1, min, max, pageSize); + update = true; + } + else + update = false; + } + + + // Below the message bounds? + else if (y >= msg.bounds.topLeft.y + msg.bounds.extent.y) + { + SclGetScrollBar (bar, &value, &min, &max, &pageSize); + if (value < max) + { + MsgScroll (1, winDown); + SclSetScrollBar (bar, value+1, min, max, pageSize); + update = true; + } + else + update = false; + } + + + // Over a different character? + else if (! RctPtInRectangle (x, y, &r)) + update = true; + + else + update = false; + + if (update) + { + msg.fieldTextPos = MessageScrollPos; + msg.fieldType = MessageTopField; + msg.fieldText = MsgGetFieldPtr (&msg); + MsgGetPositionOfPoint (&msg, x, y, &penFld, &penPos, &r); + + msg.fieldTextPos = MessageScrollPos; + msg.fieldType = MessageTopField; + msg.fieldText = MsgGetFieldPtr (&msg); + MsgSetSelection (&msg, penFld, penPos, anchorFld, anchorPos); + } + + PenGetPoint (&x, &y, &penDown); + } while (penDown); + + MemHandleUnlock (msg.recordH); + FntSetFont (currFont); +} + + +/*********************************************************************** + * + * FUNCTION: MsgCopySelectedField + * + * DESCRIPTION: This routine a selected message field to the passed handle. + * + * PARAMETERS: msg - structure containing message info + * selectField - type of the field to copy + * destH - handle to copy to + * srcP - text of the message field to copy + * appendLinefeed - true + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 10/2/96 Initial Revision + * + ***********************************************************************/ +static Boolean MsgCopySelectedField (MessegeInfoPtr msg, MsgSelectFieldType selectField, + MemHandle destH, Char * srcP, Boolean appendLinefeed) +{ + Err err; + UInt16 size; + UInt16 newSize; + UInt16 length = 0; + UInt16 endPos; + UInt16 startPos; + Char * destP; + Boolean truncated = false; + + if (srcP) + { + if (selectField == msg->selectStartField) + startPos = msg->selectStartPos; + else + startPos = 0; + + if (selectField == msg->selectEndField) + endPos = msg->selectEndPos; + else + endPos = StrLen (srcP); + + length = endPos - startPos; + } + + + size = MemHandleSize (destH); + + if (size + length > maxCopyLength) + { + length = maxCopyLength - size; + truncated = true; + } + + newSize = size + length; + if (appendLinefeed) + newSize++; + + err = MemHandleResize (destH, newSize); + if (err) return (true); + + destP = MemHandleLock (destH); + destP += size-1; + if (srcP) + { + MemMove (destP, srcP+startPos, length); + destP += length; + } + + // Add a linefeed to the end of the string. + if (appendLinefeed) + { + *destP = linefeedChr; + destP++; + } + + // Null terminate the string. + *destP = 0; + MemHandleUnlock (destH); + + return (truncated); +} + + +/*********************************************************************** + * + * FUNCTION: MsgCopy + * + * DESCRIPTION: This routine copies the current selection to the clipboard. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 10/2/96 Initial Revision + * + ***********************************************************************/ +void MsgCopy (void) +{ + Char * ptr; + MemHandle resH = 0; + MemHandle destH; + Boolean appendLinefeed; + Boolean truncated = false; + MsgFieldType topField; + MessegeInfoType msg; + MsgSelectFieldType selectField; + + if (MessageSelectStartField == msgSelectNone) + return; + + // Allocate a handle just large enough to hold a null-terminator. + destH = MemHandleNew (1); + if (! destH) return; + + ptr = MemHandleLock (destH); + *ptr = 0; + MemPtrUnlock (ptr); + + + if (ShowFullHeader) + topField = msgFieldTo; + else + topField = msgFieldSentTo; + + MsgInit (&msg, topField, 0); + + while (true) + { + if (msg.fieldText && *msg.fieldText) + { + for (selectField = msg.selectStartField; + selectField <= msg.selectEndField; selectField++) + { + if (MsgSelectFieldVisible (&msg, selectField)) + { + if (MsgIsLableField (selectField)) + { + resH = MsgGetHeaderLabel (msg.fieldType, + (MailAddressingType) msg.record.flags.addressing); + ptr = MemHandleLock (resH); + appendLinefeed = false; + } + else + { + ptr = msg.fieldText + msg.fieldTextPos; + switch (selectField) + { + case msgSelectSentTo: + case msgSelectTo: + case msgSelectFrom: + case msgSelectSubject: + case msgSelectCC: + case msgSelectDate: + appendLinefeed = (msg.selectEndField > selectField || + (msg.selectEndField == selectField && + msg.selectEndPos == StrLen (ptr))); + break; + default: + appendLinefeed = false; + } + } + + if (MsgCopySelectedField (&msg, selectField, destH, ptr, appendLinefeed)) + truncated = true; + + if (resH) + { + MemHandleUnlock (resH); + DmReleaseResource (resH); + resH = 0; + } + } + } + } + + else if (msg.fieldType == msgFieldBlankLine && + msg.selectStartField <= msgSelectBlankLine && + msg.selectEndField >= msgSelectBlankLine) + { + if (MsgCopySelectedField (&msg, msgSelectBlankLine, destH, NULL, true)) + truncated = true; + } + + if (! MsgNextField (&msg)) + break; + } + + MemHandleUnlock (msg.recordH); + + + ptr = MemHandleLock (destH); + + if (! truncated) + ClipboardAddItem (clipboardText, ptr, StrLen (ptr)); + else + FrmAlert (ClipboardLimitAlert); + + + MemPtrFree (ptr); +} + + +/*********************************************************************** + * + * FUNCTION: MsgSelectAll + * + * DESCRIPTION: This routine selects an entire message. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 10/3/96 Initial Revision + * + ***********************************************************************/ +void MsgSelectAll (void) +{ + FontID currFont; + UInt16 endPos; + MessegeInfoType msg; + + currFont = FntSetFont (MessageFont); + + MsgInit (&msg, MessageTopField, MessageScrollPos); + + // Cancel the existing selection + MsgSetSelection (&msg, msgSelectNone, 0, msgSelectNone, 0); + + msg.fieldTextPos = MessageScrollPos; + msg.fieldType = MessageTopField; + msg.fieldText = MsgGetFieldPtr (&msg); + + endPos = StrLen (msg.record.body); + MsgSetSelection (&msg, msgSelectSentToLabel, 0, msgSelectBody, endPos); + + MemHandleUnlock (msg.recordH); + FntSetFont (currFont); +} + + +/*********************************************************************** + * + * FUNCTION: MsgChangeFont + * + * DESCRIPTION: This routine change the font used to display a mail message. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 12/15/96 Initial Revision + * + ***********************************************************************/ +void MsgChangeFont (void) +{ + UInt16 pos; + UInt16 length; + UInt16 lineNumber; + UInt16 linesToDraw; + FontID currFont; + MessegeInfoType msg; + + currFont = FntSetFont (MessageFont); + + MsgInit (&msg, MessageTopField, 0); + +//set the view to the top of the current field +MsgPreviousField (&msg); +MsgNextField (&msg); +MessageScrollPos = 0; + + pos = 0; + lineNumber = 0; + linesToDraw = msg.bounds.extent.y / FntLineHeight (); + + while (lineNumber < linesToDraw) + { + length = MsgWordWrap (&msg); + if (length) + { + msg.fieldTextPos += length; + if (MessageTopField == msg.fieldType) + { + if (msg.fieldTextPos < MessageScrollPos) + pos = msg.fieldTextPos; + else if (msg.fieldTextPos == MessageScrollPos) + { + pos = msg.fieldTextPos; + lineNumber++; + } + else + lineNumber++; + } + else + lineNumber++; + } + else if (msg.fieldType == msgFieldBlankLine) + { + lineNumber++; + if (! MsgNextField (&msg)) + break; + } + else if (!MsgNextField (&msg)) + break; + } + + MessageScrollPos = pos; + + MemHandleUnlock (msg.recordH); + + if (lineNumber < linesToDraw && pos != 0 && + (MessageTopField != msgFieldTo || MessageTopField == msgFieldSentTo)) + { + MsgScroll (linesToDraw - lineNumber, winUp); + } + else + { + MsgErase (); + MsgDraw (); + } + + FntSetFont (currFont); +} diff --git a/handera-sdk-105/examples/Mail/Src/MailMessage.h b/handera-sdk-105/examples/Mail/Src/MailMessage.h new file mode 100644 index 0000000..e49bac8 --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/MailMessage.h @@ -0,0 +1,65 @@ +/****************************************************************************** + * + * Copyright (c) 1996-1999 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MailMessage.h + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This file defines the massage viewing structures and functions of + * the msg application. + * + * History: + * June 20, 1996 Created by Art Lamb + * + *****************************************************************************/ + +// Used by message selection routions. +typedef enum { + msgSelectSentToLabel, + msgSelectSentTo, + msgSelectToLabel, + msgSelectTo, + msgSelectFromLabel, + msgSelectFrom, + msgSelectCCLabel, + msgSelectCC, + msgSelectSubjectLabel, + msgSelectSubject, + msgSelectDateLabel, + msgSelectDate, + msgSelectBlankLine, + msgSelectBody, + msgSelectNone } MsgSelectFieldType; + + +typedef enum { + msgFieldSentTo, + msgFieldTo, + msgFieldFrom, + msgFieldSubject, + msgFieldCC, + msgFieldDate, + msgFieldBlankLine, + msgFieldBody } MsgFieldType; + + +extern void MsgDraw (void); + +extern void MsgErase (void); + +extern void MsgGetScrollValues (UInt16 * textHeightP, UInt16 * pageHeightP, UInt16 * topLineP); + +extern void MsgScroll (Int16 linesToScroll, WinDirectionType direction); + +extern Boolean MsgSearch (MailDBRecordPtr recordP, Char * strToFind, UInt16 * fieldNumP, UInt16 * posP, UInt16 *matchLenP); + +extern void MsgSelect (Int16 x, Int16 y); + +extern void MsgCopy (void); + +extern void MsgSelectAll (void); + +extern void MsgChangeFont (void); diff --git a/handera-sdk-105/examples/Mail/Src/MailRsc.h b/handera-sdk-105/examples/Mail/Src/MailRsc.h new file mode 100644 index 0000000..382cb84 --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/MailRsc.h @@ -0,0 +1,256 @@ +/****************************************************************************** + * + * Copyright (c) 1996-2000 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MailRsc.h + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This file defines the ID of the resources used by the Mail + * application. + * + * History: + * May 31, 1996 Created by Art Lamb + * + *****************************************************************************/ + +// List View +#define ListView 1000 +#define ListCategoryTrigger 1003 +#define ListCategoryList 1004 +#define ListNewButton 1005 +#define ListShowButton 1006 +#define ListTable 1007 +#define ListScrollBar 1008 +//mgmg newTitle +#define ListTitleLabel 1001 + + +// Message View +#define MessageView 1100 +//mgmg new +#define MessageTitleLabel 1102 + +#define MessageAbbrHeaderButton 1103 +#define MessageFullHeaderButton 1104 +#define MessageField 1105 // DOLATER ??? - remove +#define MessageGadget 1105 +#define MessageScrollBar 1106 +#define MessageDoneButton 1107 +#define MessageReplyButton 1108 +#define MessageUnsendButton 1109 +#define MessageEditButton 1110 +#define MessageDeleteButton 1112 +#define MessageUndeleteButton 1113 +//#define MessageSmallFontButton 1113 +//#define MessageLargeFontButton 1114 +#define MessageHeaderGroup 1 +//#define MessageFontGroup 2 + +#define MessagePrevMessageButton 1111 +#define MessageNextMessageButton 1114 + + +// Message Creation View +#define NewView 1200 +#define NewSendButton 1202 +#define NewCancelButton 1203 +#define NewDetailsButton 1204 +#define NewTable 1205 +#define NewScrollBar 1206 + + +// Message Edit View (full screen) +#define EditView 1300 +#define EditField 1302 +#define EditScrollBar 1303 +#define EditDoneButton 1304 +#define EditLookupButton 1305 +#define EditSendButton 1306 +//#define EditSmallFontButton 1307 +//#define EditLargeFontButton 1308 +//#define EditFontGroup 2 + + +// Options Dialog +#define OptionsDialog 1400 +#define OptionsSortByTrigger 1404 +#define OptionsSortByList 1405 +#define OptionsShowDates 1406 +#define OptionsOkButton 1407 +#define OptionsCancelButton 1408 + + +// Details Dialog Box +#define DetailsDialog 1500 +#define DetailsPriorityTrigger 1504 +#define DetailsPriorityList 1505 +#define DetailsBCCCheckbox 1507 +#define DetailsSignatureCheckbox 1509 +#define DetailsReadCheckbox 1511 +#define DetailsDeliveryCheckbox 1513 +#define DetailsOkButton 1514 +#define DetailsCancelButton 1515 + +// Preferences Dialog Box +#define PrefDialog 1600 +#define PrefConfirmDeleteCheckbox 1602 +#define PrefSignatureField 1604 +#define PrefOkButton 1605 +#define PrefCancelButton 1606 +#define PrefDefaultMailTrigger 1608 +#define PrefDefaultMailList 1609 + +// Reply Options Dialog Box +#define ReplyDialog 1700 +#define ReplyToSenderPushButton 1703 +#define ReplyToAllPushButton 1704 +#define ReplyForwardPushButton 1705 +#define ReplayIncludeTextCheckbox 1706 +#define ReplyCommentTextCheckbox 1707 +#define ReplyOkButton 1708 +#define ReplyCancelButton 1709 +#define ReplyToGroup 1 + +// Sync Options Dialog Box +#define SyncDialog 1800 + +//mgmg syncUnread +#define SyncUnreadPushButton 1801 +#define SyncUnreadLabel 1803 + +#define SyncSettingsTrigger 1804 +#define SyncSettingsList 1805 +#define SyncAllPushButton 1806 +#define SyncSendOnlyPushButton 1807 +#define SyncFilterPushButton 1808 +#define SyncAllLabel 1809 +#define SyncSendOnlyLabel 1810 +#define SyncRetrieveAllCheckbox 1811 +#define SyncMessageContaingTrigger 1813 +#define SyncMessageContaingList 1814 +#define SyncToButton 1815 +#define SyncToField 1816 +#define SyncFromButton 1817 +#define SyncFromField 1818 +#define SyncSubjectButton 1819 +#define SyncSubjectField 1820 +#define SyncOkButton 1821 +#define SyncCancelButton 1822 +#define SyncTruncateButton 1823 +#define SyncTypeGroup 1 + +// Truncate Options Dialog Box +#define TruncateDialog 1900 +#define TruncateList 1903 +#define TruncateOkButton 1904 +#define TruncateCancelButton 1905 + +// Delete Message Alert +#define DeleteMessageAlert 2001 +#define DeleteMessageYes 0 +#define DeleteMessageNo 1 + +// File Message Alert +#define FileMessageAlert 2002 +#define FileMessageYes 0 +#define FileMessageNo 1 +#define FileMessageCancel 2 + +// No To Address Alert +#define NoAddressAlert 2003 + +// No To Address Alert +#define PurgeAlert 2004 +#define PurgeYes 0 +#define PurgeNo 1 + +// Save Draft Alert +#define SaveDraftAlert 2005 +#define SaveDraftYes 0 +#define SaveDraftNo 1 +#define SaveDraftCancel 2 + +// Nothing To Purge Alert +#define NothingToPurgeAlert 2006 + +//mgmg new +#define RomIncompatibleAlert 2007 +#define SaveEmptyAlert 2008 + +// Menus +#define ListViewMenu 1000 +#define NoteViewMenu 1001 + +#define newMenuCmd 100 +#define purgeMenuCmd 101 + +#define ListChangeFontMenuCmd 200 +#define preferencesMenuCmd 201 +#define hotSyncMenuCmd 202 +#define aboutMenuCmd 203 + +#define messageNewMenuCmd 300 +#define messageFileMenuCmd 301 +#define messagePurgeMenuCmd 302 + +#define messageCopyCmd 400 +#define messageSelectAllCmd 401 + + +#define messageChangeFontCmd 500 +#define messagePreferencesMenuCmd 501 +#define messageHotSyncMenuCmd 502 +#define messageAboutMenuCmd 503 + +#define newSaveDraftMenuCmd 600 +#define newPurgeMenuCmd 601 + +#define newChangeFontMenuCmd 700 +#define newPreferencesMenuCmd 701 +#define newHotSyncMenuCmd 702 +#define newLookupMenuCmd 703 +#define newAboutMenuCmd 704 + +#define editChangeFontCmd 900 +#define editLookupMenuCmd 901 + +// Strings +#define findHeaderStrId 100 +#define toStrId 101 +#define fromStrId 102 +#define subjectStrId 103 +#define ccStrId 104 +#define dateStrId 105 +#define bccStrId 106 +#define newViewLabelsStrId 107 +#define editViewTitlesStrId 108 +#define listTitleStringId 109 +#define replyPrefixStrId 110 +#define forwardPrefixStrId 111 +#define forwardMessageStrId 112 +#define wroteOnStrId 113 +#define mailToLookupTitleStrID 114 +#define mailFromLookupTitleStrID 115 +#define mailCCLookupTitleStrID 116 +#define mailBCCLookupTitleStrID 117 +#define mailLookupAddStrID 118 +#define mailLookupFormatStrID 119 +#define noSubjectStrID 120 +#define filterIgnoreStrID 121 +#define purgeTipText 122 +#define noSubjectListViewStrID 123 +#define noToListViewStrID 124 +#define listTitleNotInboxStringId 125 +#define MessageTitleStrID 126 +#define listTitleSingularStringId 127 +#define listTitleNotInboxSingularStrId 128 +#define listTitleShortStrID 129 +#define mailAddlLookupFormatStrID 130 + +//BITMAPS +#define readUrgentIconID 1000 +#define readIconID 1001 +#define urgentIconID 1002 diff --git a/handera-sdk-105/examples/Mail/Src/MailSync.c b/handera-sdk-105/examples/Mail/Src/MailSync.c new file mode 100644 index 0000000..ee995cd --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/MailSync.c @@ -0,0 +1,928 @@ +/****************************************************************************** + * + * Copyright (c) 1996-1999 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MailSync.c + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * The file contains routines the manage the Mail application's + * HotSync options. + * + * History: + * July 29, 1996 Created by Art Lamb + * + *****************************************************************************/ + +#include + +#include "Mail.h" +/* HandEra */ +#include "vga.h" +/* end HandEra */ + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ + +#define localHotSyncItem 0 +#define remoteHotSyncItem 1 + +static void SyncApply (void); +static void SyncChangeSyncType (UInt16 controlID); +static MemHandle SyncSaveUIState (Boolean local); +static void SyncSavePreferences (Boolean local); +static void SyncLoadPreferences (Boolean local); +static void SyncInitFilter (UInt16 fieldID, Char * filter, UInt16 len); +static void SyncInit (void); +static void SyncRestoreUIState (MemHandle stateH); + + +/* HandEra */ +static VgaScreenStateType gScreenState; +/* end HandEra */ + +/*********************************************************************** + * + * FUNCTION: ShowObject + * + * DESCRIPTION: This routine set an object usable and draws the object if + * the form it is in is visible. + * + * PARAMETERS: frm - pointer to a form + * objectID - id of the object to set usable + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * + ***********************************************************************/ +static void ShowObject (FormPtr frm, UInt16 objectID) +{ + FrmShowObject (frm, FrmGetObjectIndex (frm, objectID)); +} + + +/*********************************************************************** + * + * FUNCTION: HideObject + * + * DESCRIPTION: This routine set an object not-usable and erases it + * if the form it is in is visible. + * + * PARAMETERS: frm - pointer to a form + * objectID - id of the object to set not usable + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 2/21/95 Initial Revision + * + ***********************************************************************/ +static void HideObject (FormPtr frm, UInt16 objectID) +{ + FrmHideObject (frm, FrmGetObjectIndex (frm, objectID)); +} + + +/*********************************************************************** + * + * FUNCTION: SyncInitFilter + * + * DESCRIPTION: This routine initialize the text value of the specified + * filter field with the string passed. + * + * PARAMETERS: fieldID id of field to initialize + * filter filter string + * len length of the filter string + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 8/1/96 Initial Revision + * + ***********************************************************************/ +static void SyncInitFilter (UInt16 fieldID, Char * filter, UInt16 len) +{ + MemHandle h; + Char * p; + FieldPtr fld; + + fld = GetObjectPtr (fieldID); + FldFreeMemory (fld); + + if (len) + { + // Copy the filter string into a new handle. + h = MemHandleNew (len+1); + p = MemHandleLock (h); + StrCopy (p, filter); + MemPtrUnlock (p); + + FldSetTextHandle (fld, h); + } + + if (FrmVisible(FrmGetActiveForm ())) + FldDrawField (fld); +} + + +/*********************************************************************** + * + * FUNCTION: SyncChangeSyncType + * + * DESCRIPTION: This routine changes the ui gadgets in the Sync Options + * Dialog Box such that they match the newly selected sync + * type. The routine is called when one of the sync type + * push buttons are pushed. + * + * PARAMETERS: controlID - id of the newly selected sync type push button + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/30/96 Initial Revision + * MGolden 7/7/97 added syncUnread option + * + ***********************************************************************/ +static void SyncChangeSyncType (UInt16 controlID) +{ + FormPtr frm; + + frm = FrmGetActiveForm (); + + switch (controlID) + { + case SyncAllPushButton: + HideObject (frm, SyncSendOnlyLabel); + HideObject (frm, SyncRetrieveAllCheckbox); + HideObject (frm, SyncMessageContaingTrigger); + HideObject (frm, SyncToButton); + HideObject (frm, SyncToField); + HideObject (frm, SyncFromButton); + HideObject (frm, SyncFromField); + HideObject (frm, SyncSubjectButton); + HideObject (frm, SyncSubjectField); +//mgmg added for syncUnread + HideObject(frm, SyncUnreadLabel); + + ShowObject (frm, SyncAllLabel); + break; + + + case SyncSendOnlyPushButton: + HideObject (frm, SyncAllLabel); + HideObject (frm, SyncRetrieveAllCheckbox); + HideObject (frm, SyncMessageContaingTrigger); + HideObject (frm, SyncToButton); + HideObject (frm, SyncToField); + HideObject (frm, SyncFromButton); + HideObject (frm, SyncFromField); + HideObject (frm, SyncSubjectButton); + HideObject (frm, SyncSubjectField); +//mgmg added for syncUnread + HideObject(frm, SyncUnreadLabel); + + ShowObject (frm, SyncSendOnlyLabel); + break; + + + case SyncFilterPushButton: + HideObject (frm, SyncAllLabel); + HideObject (frm, SyncSendOnlyLabel); +//mgmg added for syncUnread + HideObject(frm, SyncUnreadLabel); + + ShowObject (frm, SyncRetrieveAllCheckbox); + ShowObject (frm, SyncMessageContaingTrigger); + ShowObject (frm, SyncToButton); + ShowObject (frm, SyncToField); + ShowObject (frm, SyncFromButton); + ShowObject (frm, SyncFromField); + ShowObject (frm, SyncSubjectButton); + ShowObject (frm, SyncSubjectField); + break; + +//mgmg added for syncUnread + case SyncUnreadPushButton: + HideObject (frm, SyncAllLabel); + HideObject (frm, SyncSendOnlyLabel); + HideObject (frm, SyncRetrieveAllCheckbox); + HideObject (frm, SyncMessageContaingTrigger); + HideObject (frm, SyncToButton); + HideObject (frm, SyncToField); + HideObject (frm, SyncFromButton); + HideObject (frm, SyncFromField); + HideObject (frm, SyncSubjectButton); + HideObject (frm, SyncSubjectField); +//mgmg added for syncUnread + ShowObject(frm, SyncUnreadLabel); + break; + } +} + + +/*********************************************************************** + * + * FUNCTION: SyncSaveUIState + * + * DESCRIPTION: This routine save the current ui settings. It is call + * before go the the Edit View to edit the to, from or + * subject filters. We will dismiss the HotSync Options + * dialog so we need to save the UI state. + * + * PARAMETERS: local - true for local sync preferences, false for + * remote sync preferences. + * + * RETURNED: handle of SyncUIStateType structure + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/20/96 Initial Revision + * + ***********************************************************************/ +static MemHandle SyncSaveUIState (Boolean local) +{ + FormPtr frm; + ListPtr lst; + FieldPtr fld; + ControlPtr ctl; + MemHandle stateH; + SyncUIStatePtr stateP; + + + frm = FrmGetActiveForm (); + + // Allocate a handle to hold the UI state. + stateH = MemHandleNew (sizeof (SyncUIStateType)); + if (! stateH) return (NULL); + stateP = MemHandleLock (stateH); + + // Local or remote HotSync options? + stateP->local = local; + + // Get the sync type (all, send only, or filter or Unread). + stateP->syncType = FrmGetControlGroupSelection (frm, SyncTypeGroup); + + // Get the "Retrieve All High Priority" checkbox setting. + ctl = GetObjectPtr (SyncRetrieveAllCheckbox); + stateP->retrieveHighPriority = (CtlGetValue (ctl) == true); + + // Get the "Ignore / Retrive Messages Containing" setting. + lst = GetObjectPtr (SyncMessageContaingList); + stateP->messageContaing = (MailFilterType) LstGetSelection (lst); + + // Get length that retrieved message should be truncated to. + stateP->maxLength = TruncateLen; + + // Get the to, from and subject filters. + fld = GetObjectPtr (SyncToField); + stateP->to = FldGetTextHandle (fld); + FldSetTextHandle (fld, 0); + + fld = GetObjectPtr (SyncFromField); + stateP->from = FldGetTextHandle (fld); + FldSetTextHandle (fld, 0); + + fld = GetObjectPtr (SyncSubjectField); + stateP->subject = FldGetTextHandle (fld); + FldSetTextHandle (fld, 0); + + MemHandleUnlock (stateH); + + return (stateH); +} + + +/*********************************************************************** + * + * FUNCTION: SyncRestoreUIState + * + * DESCRIPTION: This routine restores the ui settings of the HotSync + * options dialog. It is call after we return from + * editing the to, from or subject filters, in the Edit + * View. We dismissed the HotSync Options before going + * to the Edit View so we need to restore the UI state. + * + * PARAMETERS: handle of SyncUIStateType structure + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 9/20/96 Initial Revision + * + ***********************************************************************/ + +static void SyncRestoreUIState (MemHandle stateH) +{ + UInt16 item; + UInt16 controlID; + Char * label; + ListPtr lst; + FormPtr frm; + ControlPtr ctl; + SyncUIStatePtr stateP; + + + frm = FrmGetActiveForm (); + + stateP = MemHandleLock (stateH); + + // Set the local / remote settings trigger. + ctl = GetObjectPtr (SyncSettingsTrigger); + lst = GetObjectPtr (SyncSettingsList); + if (stateP->local) + item = localHotSyncItem; + else + item = remoteHotSyncItem; + label = LstGetSelectionText (lst, item); + CtlSetLabel (ctl, label); + LstSetSelection (lst, item); + + + // Set the Sync tye (All, Send Only, or Filter) push button. + controlID = FrmGetObjectId (frm, stateP->syncType); + FrmSetControlGroupSelection (frm, SyncTypeGroup, controlID); + + // Enable / Disable the proper ui gadgets. + SyncChangeSyncType (controlID); + + // Set the "Retrieve All High Priority" checkbox. + ctl = GetObjectPtr (SyncRetrieveAllCheckbox); + CtlSetValue (ctl, (stateP->retrieveHighPriority == true)); + + + // Set the "Ignore / Retrive Messages Containing" trigger and poup + // list. + ctl = GetObjectPtr (SyncMessageContaingTrigger); + lst = GetObjectPtr (SyncMessageContaingList); + label = LstGetSelectionText (lst, stateP->messageContaing); + CtlSetLabel (ctl, label); + LstSetSelection (lst, stateP->messageContaing); + + // Set length that retrieved message should be truncated to. + TruncateLen = stateP->maxLength; + + // Set the to, from and subject filters. + FldSetTextHandle (GetObjectPtr (SyncToField), stateP->to); + FldSetTextHandle (GetObjectPtr (SyncFromField), stateP->from); + FldSetTextHandle (GetObjectPtr (SyncSubjectField), stateP->subject); + + MemPtrFree (stateP); +} + + +/*********************************************************************** + * + * FUNCTION: SyncLoadPreferences + * + * DESCRIPTION: This routine load the specified HotSync preferences + * (local or remote) and initial the dialog's ui. + * + * PARAMETERS: local - true for local sync preferences, false for + * remote sync preferences. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/30/96 Initial Revision + * MGolden 7/7/97 added syncUnread option + * + ***********************************************************************/ +static void SyncLoadPreferences (Boolean local) +{ + UInt16 len; + UInt16 rscID; + UInt16 prefsSize; + UInt16 controlID; + Int16 version; + Char * label; + Char * filter; + ListPtr lst; + FormPtr frm; + ControlPtr ctl; + SyncPreferencesType prefs; + SyncPreferencesPtr prefsP; + + frm = FrmGetActiveForm (); + + if (local) + rscID = mailLocalSyncPrefID; + else + rscID = mailRemoteSyncPrefID; + + + // Get the HotSync preferences. + prefsSize = sizeof (SyncPreferencesType); + version = PrefGetAppPreferences (sysFileCMail, rscID, &prefs, &prefsSize, true); + if (version == noPreferenceFound) + { + controlID = SyncAllPushButton; + prefs.retrieveHighPriority = true; + prefs.messageContaing = ingoreContaining; + + TruncateLen = syncDefaultMaxMsgLen; + } + + else + { +//mgmg syncUnread + switch (prefs.syncType) + { + case syncAll: + controlID = SyncAllPushButton; + break; + + case syncSendOnly: + controlID = SyncSendOnlyPushButton; + break; + + case syncFilter: + controlID = SyncFilterPushButton; + break; + + case syncUnread: + controlID = SyncUnreadPushButton; + break; + + default: + //just in case...set it to all + controlID = SyncAllPushButton; + break; + }//switch +/* old + if (prefs.syncType == syncAll) + { + controlID = SyncAllPushButton; + } + + else if (prefs.syncType == syncSendOnly) + { + controlID = SyncSendOnlyPushButton; + } + + else + { + controlID = SyncFilterPushButton; + } +*/ + + TruncateLen = prefs.maxLength; + } + + + // Set the Sync tye (All, Send Only, or Filter) push button. + FrmSetControlGroupSelection (frm, SyncTypeGroup, controlID); + + + // Enable / Disable the proper ui gadgets. + SyncChangeSyncType (controlID); + + // Set the "Retrieve All High Priority" checkbox. + ctl = GetObjectPtr (SyncRetrieveAllCheckbox); + CtlSetValue (ctl, (prefs.retrieveHighPriority == true)); + + + // Set the "Ignore / Retrive Messages Containing" trigger and poup + // list. + ctl = GetObjectPtr (SyncMessageContaingTrigger); + lst = GetObjectPtr (SyncMessageContaingList); + label = LstGetSelectionText (lst, prefs.messageContaing); + CtlSetLabel (ctl, label); + LstSetSelection (lst, prefs.messageContaing); + + + // Get the rest of the preferences, the filter strings are at the + // of the preferences. + if (version != noPreferenceFound) + { + prefsP = MemPtrNew (prefsSize); + if (! prefsP) return; + + PrefGetAppPreferences (sysFileCMail, rscID, prefsP, &prefsSize, true); + + filter = ((Char *)prefsP) + sizeof (SyncPreferencesType); + len = StrLen (filter); + SyncInitFilter (SyncToField, filter, len); + + filter += len + 1; + len = StrLen (filter); + SyncInitFilter (SyncFromField, filter, len); + + filter += len + 1; + len = StrLen (filter); + SyncInitFilter (SyncSubjectField, filter, len); + + MemPtrFree (prefsP); + } + + else + { + SyncInitFilter (SyncToField, NULL, 0); + SyncInitFilter (SyncFromField, NULL, 0); + SyncInitFilter (SyncSubjectField, NULL, 0); + } +} + + +/*********************************************************************** + * + * FUNCTION: SyncSavePreferences + * + * DESCRIPTION: This routine save the specified HotSync preferences + * (local or remote) based on the dialog's ui settings + * + * PARAMETERS: local - true for local sync preferences, false for + * remote sync preferences. + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 8/1/96 Initial Revision + * MGolden 7/7/97 added syncUnread option + * + ***********************************************************************/ +static void SyncSavePreferences (Boolean local) +{ + UInt16 prefID; + UInt16 prefsSize; + UInt16 controlID; + Char * ptr; + Char * filter; + FormPtr frm; + ListPtr lst; + FieldPtr toFld; + FieldPtr fromFld; + FieldPtr subjectFld; + ControlPtr ctl; + SyncPreferencesPtr prefsP; + + + // Local or remote HotSync options? + if (local) + prefID = mailLocalSyncPrefID; + else + prefID = mailRemoteSyncPrefID; + + + // Allocate a handle to hold the preferences. + toFld = GetObjectPtr (SyncToField); + fromFld = GetObjectPtr (SyncFromField); + subjectFld = GetObjectPtr (SyncSubjectField); + + prefsSize = sizeof (SyncPreferencesType) + + FldGetTextLength (toFld) + + FldGetTextLength (fromFld) + + FldGetTextLength (subjectFld) + 3; + + prefsP = MemPtrNew (prefsSize); + if (! prefsP) return; + + + // Get the sync type (all, send only, or filter). + frm = FrmGetActiveForm (); + controlID = FrmGetObjectId (frm, + FrmGetControlGroupSelection (frm, SyncTypeGroup)); +//new syncUnread + switch( controlID ) + { + case SyncAllPushButton: + prefsP->syncType = syncAll; + break; + + case SyncSendOnlyPushButton: + prefsP->syncType = syncSendOnly; + break; + + case SyncFilterPushButton: + prefsP->syncType = syncFilter; + break; + + case SyncUnreadPushButton: + prefsP->syncType = syncUnread; + break; + + default: + //just in case...set it to all... + prefsP->syncType = syncAll; + break; + + }//switch +/* old + if (controlID == SyncAllPushButton) + prefsP->syncType = syncAll; + else if (controlID == SyncSendOnlyPushButton) + prefsP->syncType = syncSendOnly; + else + prefsP->syncType = syncFilter; +*/ + + // Get the "Retrieve All High Priority" checkbox setting. + ctl = GetObjectPtr (SyncRetrieveAllCheckbox); + prefsP->retrieveHighPriority = (CtlGetValue (ctl) == true); + + + // Get the "Ignore / Retrive Messages Containing" setting. + lst = GetObjectPtr (SyncMessageContaingList); + prefsP->messageContaing = (MailFilterType) LstGetSelection (lst); + + + prefsP->maxLength = TruncateLen; + + + // Copy the filter strings to the end of the preferences. + filter = ((Char *)prefsP) + sizeof (SyncPreferencesType); + ptr = FldGetTextPtr (toFld); + if (ptr) + { + StrCopy (filter, ptr); + filter += StrLen(ptr) + 1; + } + else + { + *filter = 0; + filter++; + } + + ptr = FldGetTextPtr (fromFld); + if (ptr) + { + StrCopy (filter, ptr); + filter += StrLen(ptr) + 1; + } + else + { + *filter = 0; + filter++; + } + + + ptr = FldGetTextPtr (subjectFld); + if (ptr) + { + StrCopy (filter, ptr); + } + else + { + *filter = 0; + } + + + // Save the preferences. + PrefSetAppPreferences (sysFileCMail, prefID, mailVersionNum, prefsP, prefsSize, true); + + MemPtrFree (prefsP); +} + + +/*********************************************************************** + * + * FUNCTION: SyncApply + * + * DESCRIPTION: This routine applies the changes made in the Sync + * Option Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/30/96 Initial Revision + * + ***********************************************************************/ +static void SyncApply (void) +{ + ListPtr lst; + + // Local or remote HotSync options? + lst = GetObjectPtr (SyncSettingsList); + SyncSavePreferences (LstGetSelection (lst) == localHotSyncItem); +} + + +/*********************************************************************** + * + * FUNCTION: SyncInit + * + * DESCRIPTION: This routine initializes the Sync Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/29/96 Initial Revision + * + ***********************************************************************/ +static void SyncInit (void) +{ + Char * label; + ListPtr lst; + FormPtr frm; + ControlPtr ctl; + + frm = FrmGetActiveForm (); + + // Set the local / remote settings trigger. + ctl = GetObjectPtr (SyncSettingsTrigger); + lst = GetObjectPtr (SyncSettingsList); + label = LstGetSelectionText (lst, localHotSyncItem); + CtlSetLabel (ctl, label); + LstSetSelection (lst, localHotSyncItem); + + + // Get the local HotSync preferences and initial the dialog's ui. + SyncLoadPreferences (true); +} + + + +/*********************************************************************** + * + * FUNCTION: SyncHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "Sync + * Options Dialog Box". + * + * 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. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 7/29/96 Initial Revision + * MGolden 7/7/97 added syncUnread option + * + ***********************************************************************/ +Boolean SyncHandleEvent (EventPtr event) +{ + UInt16 controlID; + FormPtr frm; + Boolean local; + Boolean handled = false; + + if (event->eType == ctlSelectEvent) + { + controlID = event->data.ctlSelect.controlID; + if (controlID == SyncOkButton) + { + SyncApply (); + FrmReturnToForm (0); +/* HandEra */ + if(vgaExists) + VgaRestoreScreenState(&gScreenState); +/* end HandEra */ + handled = true; + } + else if (controlID == SyncCancelButton) + { + FrmReturnToForm (0); +/* HandEra */ + if(vgaExists) + VgaRestoreScreenState(&gScreenState); +/* end HandEra */ + handled = true; + } + else if (controlID == SyncTruncateButton) + { + FrmPopupForm (TruncateDialog); + } + else if ( (controlID == SyncAllPushButton) || + (controlID == SyncSendOnlyPushButton) || + (controlID == SyncFilterPushButton) || + (controlID == SyncUnreadPushButton)) + { + SyncChangeSyncType (event->data.ctlSelect.controlID); + } + + else if ( (controlID == SyncToButton) || + (controlID == SyncFromButton) || + (controlID == SyncSubjectButton)) + { + if (controlID == SyncToButton) + EditViewField = editToField; + else if (controlID == SyncFromButton) + EditViewField = editFromField; + else + EditViewField = editSubjectField; + + EditViewEditRecord = false; + local = (LstGetSelection (GetObjectPtr (SyncSettingsList)) == localHotSyncItem); + SyncUIStateH = SyncSaveUIState (local); + FrmGotoForm (EditView); + } + +#ifdef USE_SWITCH_STATEMENT + switch (controlID) + { + case SyncOkButton: + SyncApply (); + FrmReturnToForm (0); +/* HandEra */ + if(vgaExists) + VgaRestoreScreenState(&gScreenState); +/* end HandEra */ + handled = true; + break; + + case SyncCancelButton: + FrmReturnToForm (0); +/* HandEra */ + if(vgaExists) + VgaRestoreScreenState(&gScreenState); +/* end HandEra */ + handled = true; + break; + + case SyncTruncateButton: + FrmPopupForm (TruncateDialog); + break; + + case SyncAllPushButton: + case SyncSendOnlyPushButton: + case SyncFilterPushButton: + +//mgmg syncUnread + case SyncUnreadPushButton: + SyncChangeSyncType (event->data.ctlSelect.controlID); + break; + + case SyncToButton: + case SyncFromButton: + case SyncSubjectButton: + if (controlID == SyncToButton) + EditViewField = editToField; + else if (controlID == SyncFromButton) + EditViewField = editFromField; + else + EditViewField = editSubjectField; + + EditViewEditRecord = false; + local = (LstGetSelection (GetObjectPtr (SyncSettingsList)) == localHotSyncItem); + SyncUIStateH = SyncSaveUIState (local); + FrmGotoForm (EditView); + break; + } +#endif + } + + + else if (event->eType == popSelectEvent) + { + if (event->data.popSelect.controlID == SyncSettingsTrigger && + event->data.popSelect.selection != event->data.popSelect.priorSelection) + { + local = event->data.popSelect.selection == localHotSyncItem; + SyncSavePreferences (! local); + SyncLoadPreferences (local); + } + } + + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); +/* HandEra */ + if(vgaExists) + VgaSaveScreenState(&gScreenState); + ToolsVgaAdjustModalForm(frm, true); +/* end HandEra */ + if ( ! SyncUIStateH) + SyncInit (); + else + { + SyncRestoreUIState (SyncUIStateH); + SyncUIStateH = 0; + } + FrmDrawForm (frm); + handled = true; + } + + return (handled); +} diff --git a/handera-sdk-105/examples/Mail/Src/MailSync.h b/handera-sdk-105/examples/Mail/Src/MailSync.h new file mode 100644 index 0000000..4226a6d --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/MailSync.h @@ -0,0 +1,88 @@ +/****************************************************************************** + * + * Copyright (c) 1996-1999 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MailSync.h + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This file defines the structures and functions of the Mail Sync + * options. + * + * History: + * July 26, 1996 Created by Art Lamb + * + *****************************************************************************/ + +// The mail sync options are stored in the following format. +// SyncFilterType +// To filter - null terminated string +// From filter - null terminated string +// Subject filter - null terminated string + +//mgmg added syncUnread for unreadOnly Sync feature +typedef enum { syncAll, syncSendOnly, syncFilter, syncUnread } MailSyncType; +//typedef enum { syncAll, syncSendOnly, syncFilter } MailSyncType; + +typedef enum { ingoreContaining, retrieveContaining } MailFilterType; + + +typedef struct { + + MailSyncType syncType; // all, send only, filter + + Boolean retrieveHighPriority;// If true then high priority messages are + // always retrieved. + + MailFilterType messageContaing; // If true then messages containing the "to", + // "from" and "subject" are retrived. If false + // then messages containing the "to", "from" and + // "subject" are ignored. + + UInt8 reserved; + + UInt16 maxLength; // The length that retrieved message should be + // truncated to. +} SyncPreferencesType; + +typedef SyncPreferencesType * SyncPreferencesPtr; + + + + +// This structure is used to save the current HotSync options ui settings +// before we go the the Edit View to edit the to, from or subject filters. +// The HotSync Options dialog is dismiss when we edit the filter so we need +// to save the UI state. +typedef struct { + + Boolean local; // true of local, false for remote + + UInt8 syncType; // index of selected sync type push button + // (all, send only, filter). + + Boolean retrieveHighPriority;// If true then high priority messages are + // always retrieved. + + MailFilterType messageContaing; // If true then messages containing the "to", + // "from" and "subject" are retrived. If false + // then messages containing the "to", "from" and + // "subject" are ignored. + + UInt16 maxLength; // The length that retrieved message should be + // truncated to. + + MemHandle to; + + MemHandle from; + + MemHandle subject; + +} SyncUIStateType; + +typedef SyncUIStateType * SyncUIStatePtr; + + +extern Boolean SyncHandleEvent (EventPtr event); diff --git a/handera-sdk-105/examples/Mail/Src/MailTruncate.c b/handera-sdk-105/examples/Mail/Src/MailTruncate.c new file mode 100644 index 0000000..081d514 --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/MailTruncate.c @@ -0,0 +1,240 @@ +/****************************************************************************** + * + * Copyright (c) 1996-1999 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MailTruncate.c + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * The file contains routines the manage the Mail application's + * HotSync truncation options. + * + * History: + * Aug 1, 1996 Created by Art Lamb + * + *****************************************************************************/ + +#include + +#include "Mail.h" + +/* HandEra */ +#include "vga.h" +/* end HandEra */ + + +/*********************************************************************** + * + * Global variables + * + ***********************************************************************/ + +extern UInt16 TruncateLen; // Maximun length of retrieved message + +/* HandEra */ +static VgaScreenStateType gScreenState; +/* end HandEra */ + +/*********************************************************************** + * + * Internal Constants + * + ***********************************************************************/ +#define truncateLen0 250 +#define truncateLen1 500 +#define truncateLen2 1000 +#define truncateLen3 2000 +#define truncateLen4 4000 +#define truncateLen5 6000 +#define truncateLen6 8000 + + +/*********************************************************************** + * + * FUNCTION: TruncateApply + * + * DESCRIPTION: This routine applies the changes made in the Truncate + * Option Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 8/1/96 Initial Revision + * MGolden 7/14/97 Removed the switch due to 16 bit link errors... + * + ***********************************************************************/ +static void TruncateApply (void) +{ + ListPtr lst; + UInt16 selection; + + lst = GetObjectPtr (TruncateList); + + selection = LstGetSelection (lst); + + if (selection == 0) + TruncateLen = truncateLen0; + else if (selection == 1) + TruncateLen = truncateLen1; + else if (selection == 2) + TruncateLen = truncateLen2; + else if (selection == 3) + TruncateLen = truncateLen3; + else if (selection == 4) + TruncateLen = truncateLen4; + else if (selection == 5) + TruncateLen = truncateLen5; + else if (selection == 6) + TruncateLen = truncateLen6; + else + TruncateLen = syncDefaultMaxMsgLen; + +/* + switch (LstGetSelection (lst)) + { + case 0: TruncateLen = truncateLen0; break; + case 1: TruncateLen = truncateLen1; break; + case 2: TruncateLen = truncateLen2; break; + case 3: TruncateLen = truncateLen3; break; + case 4: TruncateLen = truncateLen4; break; + case 5: TruncateLen = truncateLen5; break; + case 6: TruncateLen = truncateLen6; break; + default: TruncateLen = syncDefaultMaxMsgLen; + } +*/ +} + + +/*********************************************************************** + * + * FUNCTION: TruncateInit + * + * DESCRIPTION: This routine initializes the Truncate Dialog. + * + * PARAMETERS: nothing + * + * RETURNED: nothing + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 8/1/96 Initial Revision + * MGolden 7/14/97 Removed the switch due to 16 bit link errors... + * + ***********************************************************************/ +static void TruncateInit (void) +{ + UInt16 item; + ListPtr lst; + + lst = GetObjectPtr (TruncateList); + + if (TruncateLen == truncateLen0) + item = 0; + else if (TruncateLen == truncateLen1) + item = 1; + else if (TruncateLen == truncateLen2) + item = 2; + else if (TruncateLen == truncateLen3) + item = 3; + else if (TruncateLen == truncateLen4) + item = 4; + else if (TruncateLen == truncateLen5) + item = 5; + else if (TruncateLen == truncateLen6) + item = 6; + else + { + item = 4; + TruncateLen = syncDefaultMaxMsgLen; + } + +/* + switch (TruncateLen) + { + case truncateLen0: item = 0; break; + case truncateLen1: item = 1; break; + case truncateLen2: item = 2; break; + case truncateLen3: item = 3; break; + case truncateLen4: item = 4; break; + case truncateLen5: item = 5; break; + case truncateLen6: item = 6; break; + default: + item = 4; + TruncateLen = syncDefaultMaxMsgLen; + } +*/ + + LstSetSelection (lst, item); +} + + +/*********************************************************************** + * + * FUNCTION: TruncateHandleEvent + * + * DESCRIPTION: This routine is the event handler for the "Truncate + * Options Dialog Box". + * + * 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. + * + * REVISION HISTORY: + * Name Date Description + * ---- ---- ----------- + * art 8/1/96 Initial Revision + * + ***********************************************************************/ +Boolean TruncateHandleEvent (EventPtr event) +{ + FormPtr frm; + Boolean handled = false; + + if (event->eType == ctlSelectEvent) + { + switch (event->data.ctlSelect.controlID) + { + case TruncateOkButton: + TruncateApply (); + FrmReturnToForm (0); +/* HandEra */ + if(vgaExists) + VgaRestoreScreenState(&gScreenState); +/* end HandEra */ + handled = true; + break; + + case TruncateCancelButton: + FrmReturnToForm (0); +/* HandEra */ + if(vgaExists) + VgaRestoreScreenState(&gScreenState); +/* end HandEra */ + handled = true; + break; + } + } + + else if (event->eType == frmOpenEvent) + { + frm = FrmGetActiveForm (); +/* HandEra */ + if(vgaExists) + VgaSaveScreenState(&gScreenState); + ToolsVgaAdjustModalForm(frm, true); +/* end HandEra */ + TruncateInit (); + FrmDrawForm (frm); + handled = true; + } + + return (handled); +} diff --git a/handera-sdk-105/examples/Mail/Src/MailTruncate.h b/handera-sdk-105/examples/Mail/Src/MailTruncate.h new file mode 100644 index 0000000..e6084c4 --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/MailTruncate.h @@ -0,0 +1,19 @@ +/****************************************************************************** + * + * Copyright (c) 1996-1999 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: MailTruncate.h + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This file defines the structures and functions of the Mail HotSync + * Truncation options. + * + * History: + * July 26, 1996 Created by Art Lamb + * + *****************************************************************************/ + +extern Boolean TruncateHandleEvent (EventPtr event); diff --git a/handera-sdk-105/examples/Mail/Src/ShellCmdMail.cp b/handera-sdk-105/examples/Mail/Src/ShellCmdMail.cp new file mode 100644 index 0000000..9d98f07 --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/ShellCmdMail.cp @@ -0,0 +1,1238 @@ +/****************************************************************************** + * + * Copyright (c) 1996-2000 Palm, Inc. or its subsidiaries. + * All rights reserved. + * + * File: ShellCmdMail.cp + * + * Release: Palm OS SDK 4.0 (63220) + * + * Description: + * This file is where customized console shell comands are kept. + * Currently this is a stub which the emulator calls when it doesn't + * recognize a command. The code here shows how to add a custom command. + * The custom command is useless, but it does provide a template to add commands. + * An application programmer can copy this file to their application + * folder and then customize it to MemHandle as many commands as they wish. + * + * History: + * Feb 26, 1996 Created by Roger Flores + * + *****************************************************************************/ + +#if 0 +#include + +#include +#include +#include + +#include "ShellCmd.h" + +typedef void ShellCmdFuncType (int argc, Char * argv[]); +typedef ShellCmdFuncType * ShellCmdFuncPtr; +typedef struct { + Char * longName; + Char * shortName; + ShellCmdFuncPtr func; +} ShellCmdInfoType; +#endif + +/*********************************************************************** + * + * Copyright (c) Palm Computing 1996 -- All Rights Reserved + * + * PROJECT: Pilot 2.0 + * + * FILE: ShellCmdMail.cp + * + * AUTHOR: Art Lamb: May 30, 1996 + * + * DECLARER: Mail + * + * DESCRIPTION: + * This file contains the console commands for Mail application. + * + ***********************************************************************/ + +// Pilot Includes +#include + +// C library Includes +#include +#include +#include + +// DB includes +#include "DateTime.h" +#include "MailDB.h" + +#include "ShellCmd.h" + + +typedef void ShellCmdFuncType (int argc, Char * argv[]); +typedef ShellCmdFuncType * ShellCmdFuncPtr; +typedef struct { + const Char * longName; + const Char * shortName; + ShellCmdFuncPtr func; +} ShellCmdInfoType; + +#pragma pcrelstrings off + +// DOLATER ??? - Put these in one of the include files +#define mailDBType 'DATA' +#define sysFileCMail 'mail' + + +/********************************************************************** + * find an open appointment database + * + * Parameters: none + ***********************************************************************/ +static DmOpenRef FindOpenedMailDatabases (void) +{ + DmOpenRef dbP=0; + LocalID dbID; + UInt16 mode; + UInt16 cardNo; + UInt32 dbType; + UInt32 dbCreator; + + do { + dbP = DmNextOpenDatabase(dbP); + if (!dbP) break; + + Err err = DmOpenDatabaseInfo(dbP, &dbID, NULL, &mode, &cardNo, NULL); + if (err) + { + ShlInsertText("\n#ERROR getting info"); + } + else + { + DmDatabaseInfo(cardNo, dbID, 0, 0, 0, 0, 0, 0, 0, 0, 0, + &dbType, &dbCreator); + + if ( (dbType == mailDBType) && (dbCreator == sysFileCMail) ) + return (dbP); + } + } while (1); + + + return(0); +} + + +/********************************************************************** + * Set the appointment application chunk to the defaults. + * + * MailSetInfoDefaults + ***********************************************************************/ +static void DoMailSetInfoDefaults(int argc, Char * argv[]) +{ + Boolean usageErr = false; + DmOpenRef dbP=0; + char text[256]; + int i; + + for (i=1; i\n", argv[0]); + ShlInsertText(text); + return; + } + + Err err = MailAppInfoInit (dbP); + if (err) { + ShlInsertText("\n##ERROR Setting defaults\n"); + } + else { + ShlInsertText("Success!\n"); + } +} + + + +/********************************************************************** + * Test the newRecord function. + * + * DoMailTestNewRecord + ***********************************************************************/ +static void DoMailNewRecords(int argc, Char * argv[]) +{ + Boolean usageErr = false; + DmOpenRef dbP=0; + UInt16 index; + char text[256]; + int i; + +#ifdef __MWERKS__ +#pragma const_strings off +#endif + + MailDBRecordType testRecord1 = { + 94, 1, 28, + {14, 30}, + {0, 1, 0, 0, priorityNormal, 0, 0 }, + "Dinner Plans", + "mary@aol.com", + "johndoe@aol.com", + "", + "", + "", + "", + "John,\nWe are meeting at Dan and Leslie's place around 8:00 PM. Don't forget " + "to bring the birthday present for Dan. See you there." + }; + + MailDBRecordType testRecord2 = { + 94, 1, 28, + {0, 0}, + {0, 1, 0, 0, priorityNormal, 0, 0 }, + "Meeting notes", + "david@palm.com", + "david@palm.com", + "", + "", + "", + "", + "no body text" + }; + + MailDBRecordType testRecord3 = { + 94, 1, 27, + {0, 0}, + {0, 1, 0, 0, priorityNormal, 0, 0 }, + "Little brother", + "Gayle Stoltz", + "Gayle Stoltz", + "", + "", + "", + "", + "no body text" + }; + + MailDBRecordType testRecord4 = { + 94, 1, 27, + {0, 0}, + {0, 1, 0, 0, priorityNormal, 0, 0 }, + "Press Release", + "connie@wilsontec", + "connie@wilsontec", + "", + "", + "", + "", + "no body text" + }; + + MailDBRecordType testRecord5 = { + 94, 1, 26, + {0, 0}, + {0, 1, 0, 0, priorityNormal, 0, 0 }, + "IR Beaming", + "michael@3com.com", + "michael@3com.com", + "", + "", + "", + "", + "no body text" + }; + +/* + MailDBRecordType testRecord1 = { + 92, 5, 30, + {0, 0}, + {1, 0, 0, 0, priorityHigh, sentCC, 0 }, + "Test Mail Message", + "joe@palm.com (Joe Sipher)", + "monty@palm.com (Monty Boyer)\nart@palm.com (Art Lamb)", + "roger@palm.com (Roger Flores)", + "mcauwet@palm (Marian Cauwet)", + "replyTo@alo.com", + "art@palm.com (Art Lamb)", + "This is a test mail message\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12" + }; + + MailDBRecordType testRecord2 = { + 92, 6, 3, + {0, 0}, + {0, 1, 0, 0, priorityHigh, 0, 0 }, + "Message Two", + "alamb@aol.com", + "Engineering@palm.com", + "monty@palm.com (Monty Boyer)\njoe@palm.com (Joe Sipher)", + "", + "", + "", + "This is test message two." + }; + + MailDBRecordType testRecord3 = { + 92, 6, 3, + {0, 0}, + {0, 0, 1, 0, 1, 0, 0 }, + "Message Three", + "Supervisor", + "Engineering@palm.com", + "", + "", + "", + "", + "This is test message three." + }; + + MailDBRecordType testRecord4 = { + 92, 6, 3, + {0, 0}, + {0, 0, 0, 1, 1, 0, 0 }, + "Message Four", + "joe (Joe Sipher)", + "Engineering@palm.com", + "", + "", + "", + "", + "This is test message four." + }; + + MailDBRecordType testRecord5 = { + 92, 6, 4, + {0, 0}, + {0, 0, 0, 0, 1, 0, 0 }, + "Message Five", + "Art", + "Engineering@palm.com", + "", + "", + "", + "", + "This is test message five." + }; + + MailDBRecordType testRecord6 = { + 92, 6, 4, + {0, 0}, + {0, 0, 0, 0, 1, 0, 0 }, + "Message Six", + "Art", + "Engineering@palm.com", + "Company", + "", + "", + "", + "This is test message six." + }; + + MailDBRecordType testRecord7 = { + 92, 6, 5, + {0, 0}, + {0, 0, 0, 0, 1, 0, 0 }, + "Message Seven", + "Art", + "Engineering@palm.com", + "", + "", + "", + "", + "This is test message seven." + }; + + MailDBRecordType testRecord8 = { + 92, 6, 5, + {0, 0}, + {0, 0, 0, 0, 1, 0, 0 }, + "Message Eight", + "Art", + "Engineering@palm.com", + "", + "", + "", + "", + "This is test message eight." + }; + + MailDBRecordType testRecord9 = { + 92, 6, 10, + {0, 0}, + {0, 0, 0, 0, 1, 0, 0 }, + "Message Nine", + "Art", + "Engineering@palm.com", + "", + "", + "", + "", + "This is test message nine." + }; + + MailDBRecordType testRecord10 = { + 92, 6, 10, + {0, 0}, + {0, 0, 0, 0, 1, 0, 0 }, + "Message Ten", + "Art", + "Engineering@palm.com", + "", + "", + "", + "", + "This is test message ten." + }; + + MailDBRecordType testRecord11 = { + 92, 6, 10, + {0, 0}, + {0, 0, 0, 0, 1, 0, 0 }, + "Message Eleven", + "Art", + "Engineering@palm.com", + "", + "", + "", + "", + "This is test message eleven." + }; + + MailDBRecordType testRecord12 = { + 92, 6, 20, + {0, 0}, + {0, 0, 0, 0, 1, 0, 0 }, + "Message Twelve", + "Art", + "Engineering@palm.com", + "", + "", + "", + "", + "This is test message Twelve." + }; +*/ + +#ifdef __MWERKS__ +#pragma const_strings reset +#endif + + for (i=1; i\n", argv[0]); + ShlInsertText(text); + return; + } + + MailNewRecord(dbP, &testRecord1, &index); + MailNewRecord(dbP, &testRecord2, &index); + MailNewRecord(dbP, &testRecord3, &index); + MailNewRecord(dbP, &testRecord4, &index); + MailNewRecord(dbP, &testRecord5, &index); +// MailNewRecord(dbP, &testRecord6, &index); +// MailNewRecord(dbP, &testRecord7, &index); +// MailNewRecord(dbP, &testRecord8, &index); +// MailNewRecord(dbP, &testRecord9, &index); +// MailNewRecord(dbP, &testRecord10, &index); +// MailNewRecord(dbP, &testRecord11, &index); +// MailNewRecord(dbP, &testRecord12, &index); + + + ShlInsertText("New records added\n"); +} + + +/********************************************************************** + * Function: PrintMailRecord + * + * Description: Print the details of an appt record. Includes + * deleted records, and the + * deleted, dirty, secret, & busy flags. + * + * Usage: PrintMailRecord (dbP, index) + * + * Revision History: + * + * Name Date Description + * ---- ---- ----------- + * kcr 10/23/95 display deleted records, sync-status flags + * + ***********************************************************************/ +static void PrintMailRecord (DmOpenRef dbP, UInt16 index) +{ + char text[256]; + LocalID chunk; + UInt16 attr; + UInt32 uniqueID; + MemHandle recordH; + MailDBRecordType record; + + + + DmRecordInfo (dbP, index, &attr, &uniqueID, &chunk); + + // Print record index. + sprintf (text, "\nIndex: %d", index); + ShlInsertText (text); + + // Print the unique id + sprintf (text, ", unique id: %ld", uniqueID); + ShlInsertText (text); + + if ((attr & dmRecAttrDelete) && + chunk) + ShlInsertText ("\tArchived"); + else if (attr & dmRecAttrDelete) + ShlInsertText ("\tDeleted"); + if (attr & dmRecAttrDirty) + ShlInsertText ("\tDirty"); + if (attr & dmRecAttrBusy) + ShlInsertText ("\tBusy"); + if (attr & dmRecAttrSecret) + ShlInsertText ("\tSecret"); + + if (attr & dmRecAttrDelete) + return; + + // Print the category + sprintf (text, "\tCategory: %d", attr & dmRecAttrCategoryMask); + ShlInsertText (text); + + + if (MailGetRecord(dbP, index, &record, &recordH) != 0) + { + ShlInsertText("Error!"); + return; + } + + // Print date + sprintf(text, "\nDate: %d/%d/%d", record.date.month, + record.date.day, record.date.year+4); + ShlInsertText(text); + + + // Print the flags + ShlInsertText ("\nFlags: "); + sprintf (text, "Priority: %d ", record.flags.priority); + ShlInsertText (text); + + if (record.flags.read) + ShlInsertText ("Read "); + + if (record.flags.signature) + ShlInsertText ("Signature "); + + if (record.flags.confirmRead) + ShlInsertText ("Confirm Read "); + + if (record.flags.confirmDelivery) + ShlInsertText ("Confirm Delivery "); + + + if (*record.subject) + { + ShlInsertText ("\nSubject: "); + ShlInsertText (record.subject); + } + + if (*record.from) + { + ShlInsertText ("\nFrom: "); + ShlInsertText (record.from); + } + + if (*record.to) + { + ShlInsertText ("\nTo: "); + ShlInsertText (record.to); + } + + if (*record.cc) + { + ShlInsertText ("\nCC: "); + ShlInsertText (record.cc); + } + + if (*record.bcc) + { + ShlInsertText ("\nBCC: "); + ShlInsertText (record.bcc); + } + + if (*record.body) + { + ShlInsertText ("\nBody: "); + ShlInsertText (record.body); + } + + ShlInsertText ("\n"); + + + MemHandleUnlock ((MemHandle)recordH); +} + + +/********************************************************************** + * Get an record and print in Address format. + * + * DoMailGetRecord + ***********************************************************************/ +static void DoMailGetRecord(int argc, Char * argv[]) +{ + Boolean usageErr = false; + DmOpenRef dbP=0; + char text[256]; + UInt16 index = 0; + int i; + + + for (i=1; i \n", argv[0]); + ShlInsertText(text); + return; + } + + PrintMailRecord (dbP, index); +} + + +/********************************************************************** + * Get an record and print in Address format. + * + * DoMailGetRecord + * + ***********************************************************************/ +static void DoMailGetAll(int argc, Char * argv[]) +{ + int i; + UInt16 index = 0; + char text[256]; + Boolean usageErr = false; + DmOpenRef dbP=0; + + if ( argc > 1 && !strcmp(argv[1], "?") ) + goto Help; + + for (i=1; i + ***********************************************************************/ +static void DoMailChangeRecord(int argc, Char * argv[]) +{ + Int16 i; + Char text[256]; + UInt16 result; + UInt16 index = 0; + Boolean usageErr = false; + MemHandle recordH; + DmOpenRef dbP = 0; + MailDBRecordType testRecord; + MailChangedFieldsType changedFields = { 0,0,0,0,0,0,0,}; + + + * (int *) &changedFields = 0; + for (i=1; i \n", argv[0]); + ShlInsertText(text); + return; + } + + + if (MailGetRecord(dbP, index, &testRecord, &recordH) != 0) + { + ShlInsertText("Error!"); + return; + } + + testRecord.date.month = 12; + changedFields.date = true; + + MemHandleUnlock ((MemHandle)recordH); + + result = MailChangeRecord (dbP, &index, &testRecord, changedFields); + + sprintf(text, "%d\n", result); + ShlInsertText(text); +} + + +/********************************************************************** + * Sort the Mail Database + * + * DoMailSync + ***********************************************************************/ +static void DoMailSync (int argc, Char * argv[]) +{ + int i; + UInt16 index = 0; + char text[256]; + Boolean usageErr = false; + DmOpenRef dbP=0; + + if ( argc > 1 && !strcmp(argv[1], "?") ) + goto Help; + + + for (i=1; i + ***********************************************************************/ +static void DoMailDefaultData(int argc, Char * argv[]) +{ + Boolean usageErr = false; + DmOpenRef dbP=0; + UInt16 index; + char text[256]; + int i; + +#if 0 // DOLATER -- Need to fix this up for LOCALEs. +#if LANGUAGE == LANGUAGE_FRENCH + MailDBRecordType testRecord1 = { + 93, 5, 19, + {11, 0}, + {0, 0, 0, 0, priorityNormal, sentTo, 0 }, + "Bienvenue", + "eurosupport@usr.com (U.S. Robotics)", + "Utilisateur de Courrier de PalmPilot", + "", + "", + "", + "Utilisateur de Courrier de PalmPilot", + "Bienvenue dans Courrier de PalmPilot!\n" + "\n" + "Pour que vos messages de système de messagerie de " + "bureau apparaissent ici, vous devez configurer " + "HotSync sur votre bureau comme suit.\n" + "\n" + "1. Installez PalmPilot Desktop à partir " + "du CD ou des disquettes de " + "distribution.\n" + "\n" + "2. Sous Windows 95/NT 4.0 PC, " + "cliquez sur l'icône de HotSync " + "dans la barre des tâches " + "et sélectionnez Personnaliser. Sous " + "Windows 3.1x, cliquez deux fois " + "sur l'icône Personnaliser du groupe " + "de programmes de PalmPilot 2.0.\n" + "\n" + "3. Sélectionnez la conduite Courrier " + "et cliquez sur le bouton Changer.\n" + "\n" + "4. Cochez la case Activer Courrier " + "de PalmPilot.\n" + "\n" + "5. Sélectionnez le système de " + "messagerie de bureau dans le " + "menu déroulant Synchroniser avec.\n" + "\n" + "6. Entrez le nom de l'utilisateur et le " + "Mot de passe utilisé pour vous " + "connecter au système de messagerie " + "de bureau.\n" + "\n" + "7. Cliquez sur le bouton d'aide pour " + "connaître le paramétrage " + "spécifique à votre système de " + "messagerie exigé pour la " + "configuration.\n" + "\n" + "8. Cliquez sur OK.\n" + "\n" + "9. Cliquez sur Terminé.\n" + "\n" + "A la prochaine synchronisation, les messages de votre boîte de réception de bureau " + "appaîtront ici. Lisez-les, répondez, transférez-les, supprimez-les ou créez-en de nouveaux " + "A la prochaine synchronisation, tous les résultats de ces actions apparaîtront " + "ici et sur le système de messagerie de bureau.\n" + "\n" + "Profitez et appréciez Courrier de PalmPilot!\n" + }; +#elif LANGUAGE == LANGUAGE_GERMAN + MailDBRecordType testRecord1 = { + 93, 5, 19, + {11, 0}, + {0, 0, 0, 0, priorityNormal, sentTo, 0 }, + "Begrüßung", + "germantechsup@usr.com (U.S. Robotics)", + "PalmPilot Mail-Benutzer", + "", + "", + "", + "PalmPilot Mail-Benutzer", + "Willkommen bei PalmPilot Mail!\n" + "\n" + "Damit Ihre Desktop E-Mails hier erscheinen können, müssen Sie die HotSync-Anwendung " + "auf Ihrem Desktop wie folgt konfigurieren:\n" + "\n" + "Installieren Sie PalmPilot Desktop von der mitgelieferten CD bzw. von Disketten.\n" + "\n" + "Unter Windows 95/NT 4.0 PC klicken Sie im Systemfach (rechts unten) auf das " + "HotSync-Symbol, und wählen Sie \"Benutzerdefiniert\".\n" + "\n" + "Unter Windows 3.1x doppelklicken Sie auf das Symbol \"Benutzerdefiniert\" in der " + "Programmgruppe \"PalmPilot 2.0.\"\n" + "\n" + "Wählen Sie das Conduit \"Mail\", und klicken Sie auf \"Ändern\".\n" + "\n" + "Klicken Sie auf \"PalmPilot aktivieren\".\n" + "\n" + "Wählen Sie unter \"Synchronisieren mit\" Ihr Desktop E-Mail-System aus.\n" + "\n" + "Geben Sie den Benutzernamen und das Kennwort ein, mit denen Sie sich gewöhnlich " + "bei Ihrem Desktop E-Mail-System anmelden.\n" + "\n" + "Klicken Sie auf \"Hilfe\", um weitere Einstellungen anzuzeigen, die Sie eventuell " + "auf Ihrem Desktop E-Mail-System konfigurieren müssen.\n" + "\n" + "Klicken Sie auf \"OK\".\n" + "\n" + "Klicken Sie auf \"Fertig\".\n" + "\n" + "Nach dem nächsten HotSync-Vorgang werden Sie Ihre Nachrichten aus dem Desktop-Ordner " + "\"Posteingang\" hier sehen. Sie können nach Belieben E-Mails verfassen, lesen, " + "beantworten und senden bzw. löschen. Wenn Sie das nächste Mal einen HotSync " + "ausführen, werden all diese Aktionen sowohl hier als auch auf Ihrem Desktop " + "E-Mail-System angezeigt.\n" + "\n" + "Viel Spaß mit PalmPilot Mail!\n" + }; +#elif (LANGUAGE == LANGUAGE_ENGLISH) && (VENDOR == VENDOR_IBM) + MailDBRecordType testRecord1 = { + 93, 6, 20, + {15, 0}, + {0, 0, 0, 0, priorityNormal, sentTo, 0 }, + "Welcome", + "WorkPad@us.ibm.com (IBM Corp.)", + "WorkPad Mail User", + "", + "", + "", + "WorkPad Mail User", + "Welcome to WorkPad Mail!\n" + "\n" + "In order for your desktop e-mail messages to appear here, you must " + "configure HotSync on your desktop as follows.\n" + "\n" + "1. Install WorkPad Desktop from \n" + " the CD provided.\n" + "2. On your Windows 95/NT 4.0 PC, \n" + " click the HotSync system tray \n" + " icon and select Custom.\n" + "3. Select the Mail conduit and\n" + " click the Change button. \n" + "4. Click on the Activate \n" + " WorkPad Mail checkbox.\n" + "5. Select the desktop e-mail \n" + " system you use in the\n" + " Synchronize with drop-winDown\n" + " menu.\n" + "6. Enter the User Name and\n" + " Password you use to log into\n" + " your desktop e-mail system.\n" + "7. Click the Help button to\n" + " learn about other settings\n" + " specific to your desktop\n" + " e-mail system that you may\n" + " need to configure.\n" + "8. Click OK.\n" + "9. Click Done.\n" + "\n" + "When you synchronize, the messages from your desktop inbox will " + "appear right here. Read, reply, forward, delete, or create new messages. " + "\n" + "The next time you synchronize, all those actions will be reflected both " + "here on your IBM WorkPad and on your desktop e-mail system.\n" + "\n" + "Enjoy WorkPad Mail!" + }; +#else + MailDBRecordType testRecord1 = { + 94, 3, 1, + {9, 0}, + {0, 0, 0, 0, priorityNormal, sentTo, 0 }, + "Welcome", + "support@palm.com(3Com Corporation)", + "Palm Mail User", + "", + "", + "", + "Palm Mail User", + "Welcome to Palm Mail!\n" + "\n" + "In order for your desktop e-mail messages to appear here, you must configure HotSync on your desktop as follows.\n" + "\n" + "1. Install Palm Desktop organizer software on the provided CD or diskettes.\n" + "\n" + "2. Click Yes to the screen that asks if you want to configure your Palm Mail settings.\n" + "\n" + "3. Follow the steps in the Mail Setup Wizard to configure your Palm Mail.\n" + "\n" + "4. You can return to Mail Setup at anytime through the Start button on your Windows 95/NT desktop. Click the Start button, highlight Programs, go to the Palm program group and highlight Mail Setup.\n" + "\n" + "When you synchronize, the messages from your desktop inbox will appear right here. Read, reply, forward, delete, or create new messages. The next time you synchronize, all those actions will be reflected both here and on your desktop e-mail system.\n" + "\n" + "Enjoy Palm Mail!" + }; +#endif +#endif + +#if __MWERKS__ +#pragma const_strings off +#endif + + MailDBRecordType testRecord1 = { + 94, 3, 1, + {9, 0}, + {0, 0, 0, 0, priorityNormal, sentTo, 0 }, + "Welcome", + "support@palm.com(3Com Corporation)", + "Palm Mail User", + "", + "", + "", + "Palm Mail User", + "Welcome to Palm Mail!\n" + "\n" + "In order for your desktop e-mail messages to appear here, you must configure HotSync on your desktop as follows.\n" + "\n" + "1. Install Palm Desktop organizer software on the provided CD or diskettes.\n" + "\n" + "2. Click Yes to the screen that asks if you want to configure your Palm Mail settings.\n" + "\n" + "3. Follow the steps in the Mail Setup Wizard to configure your Palm Mail.\n" + "\n" + "4. You can return to Mail Setup at anytime through the Start button on your Windows 95/NT desktop. Click the Start button, highlight Programs, go to the Palm program group and highlight Mail Setup.\n" + "\n" + "When you synchronize, the messages from your desktop inbox will appear right here. Read, reply, forward, delete, or create new messages. The next time you synchronize, all those actions will be reflected both here and on your desktop e-mail system.\n" + "\n" + "Enjoy Palm Mail!" + }; + +#if __MWERKS__ +#pragma const_strings reset +#endif + + for (i=1; i\n", argv[0]); + ShlInsertText(text); + return; + } + + MailNewRecord(dbP, &testRecord1, &index); + + + ShlInsertText("New records added\n"); +} + + +/********************************************************************** + * Support for Mail commands + * + * returns 0 if successfully found command + ***********************************************************************/ +int ShlDoAppCmd(int argc, Char * argv[]) +{ + int i; + ShellCmdInfoType cmd [] ={ + "MailAppInfoInit", "msi", DoMailSetInfoDefaults, + "MailNew", "mnr", DoMailNewRecords, + "MailGetRecord", "mgr", DoMailGetRecord, + "MailGetAll", "md", DoMailGetAll, + "MailChangeRecord", "mcr", DoMailChangeRecord, + "MailSync", "ms", DoMailSync, + "MailDefaultData", "mdd", DoMailDefaultData, + }; + + for (i = 0; i < sizeof (cmd) / sizeof (ShellCmdInfoType); i++) + { + if ( (!ShlStrCmpi(argv[0], cmd[i].longName)) || + (!ShlStrCmpi(argv[0], cmd[i].shortName))) + { + cmd[i].func (argc, argv); + return 0; + } + } + return 1; +} + + + +#ifdef OLDWAY +/*********************************************************************** + * + * Copyright (c) Palm Computing 1996 -- All Rights Reserved + * + * PROJECT: Pilot + * FILE: ShellCmdUser.c + * AUTHOR: Roger Flores: Feb 26, 1996 + * + * DESCRIPTION: + * This file is where customized console shell comands are kept. + * Currently this is a stub which the emulator calls when it doesn't + * recognize a command. The code here shows how to add a custom command. + * The custom command is useless, but it does provide a template to add commands. + * An application programmer can copy this file to their application + * folder and then customize it to MemHandle as many commands as they wish. + * + **********************************************************************/ + +#include + +#include +#include +#include + +#include "ShellCmd.h" + +typedef void ShellCmdFuncType (int argc, Char * argv[]); +typedef ShellCmdFuncType * ShellCmdFuncPtr; +typedef struct { + Char * longName; + Char * shortName; + ShellCmdFuncPtr func; +} ShellCmdInfoType; + + + +/*********************************************************************** + * + * FUNCTION: DoAppCommand + * + * DESCRIPTION: Execute a user defined command for the appliation. + * (It currently adds one to a number as an example) + * + * Syntax: UserCommand num + * + * PARAMETERS: argc - number of arguments + * argv - argument list + * + * RETURNED: false if the command was a ui command. + * + ***********************************************************************/ +static void DoAppCommand (int argc, Char * argv[]) +{ + int i; + char text[256]; + Int16 num = 0; + Boolean usageErr = false; + + // Parse the arguments passed. + if ( argc > 1 && !strcmp(argv[1], "?") ) + goto Help; + + if (argc < 2) usageErr = true; + for (i=1; i +#include + +#define TRGSysFtrID 'TRG ' + +#ifdef __GNUC__ + +#define _TRG_CALL_WITH_16BIT_SELECTOR(table, vector, selector)\ + __attribute__ ((__callseq__ (\ + "move.w #" _Str(selector) ",%%d2; "\ + "trap #" _Str(table) "; dc.w " _Str(vector) ))) + +#elif defined (__MWERKS__) /* The equivalent in CodeWarrior syntax */ + +#define _TRG_CALL_WITH_16BIT_SELECTOR(table, vector, selector) \ + = { 0x343C, selector, 0x4E40 + table, vector } + +#endif + +#define TRG_TRAP(sel) \ + _TRG_CALL_WITH_16BIT_SELECTOR(_SYSTEM_TABLE, sysTrapOEMDispatch, sel) + +#ifdef BUILDING_EXTENSION + #define EXT_TRAP(x) +#else + #define EXT_TRAP(x) TRG_TRAP(x) +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + + +#endif diff --git a/handera-sdk-105/examples/Mail/Src/Vga.h b/handera-sdk-105/examples/Mail/Src/Vga.h new file mode 100644 index 0000000..38d4cb9 --- /dev/null +++ b/handera-sdk-105/examples/Mail/Src/Vga.h @@ -0,0 +1,368 @@ +/**************************************************************************** + * + * Copyright (c) 2001, TRG, All Rights Reserved + * + *--------------------------------------------------------------------------- + * FileName: + * Vga.h + * + * Description: + * VGA API definitions. + * + * + ****************************************************************************/ + +#ifndef __VGA_H__ +#define __VGA_H__ + +#include "Trg.h" + +#define TRGVgaFtrNum 2 + +/*-------------------------------------------------------------------------- + * Vga result codes + * (oemErrorClass is reserved for Palm licensees). + *-------------------------------------------------------------------------*/ +#define vgaErrorClass (oemErrorClass | 0x200) + +#define vgaErrUnimplemented (vgaErrorClass | 0) // function not implemented (on this hardware) +#define vgaErrBadParam (vgaErrorClass | 1) // invalid parameter +#define vgaErrModeUnsupported (vgaErrorClass | 2) // does not support screen mode +#define vgaErrScreenLocked (vgaErrorClass | 3) // ??? +#define vgaErrFontUndefined (vgaErrorClass | 4) // ??? + +/*--------------------------------------------------------------------------- + * Extension Installed + *--------------------------------------------------------------------------*/ +#define _TRGVGAFeaturePresent(versionPtr) \ + (Boolean)(FtrGet(TRGSysFtrID, TRGVgaFtrNum, versionPtr) == 0) + + +/*--------------------------------------------------------------------------- + * Notification that the screen area changed (silk minimize/maximized, rotation) + *--------------------------------------------------------------------------*/ +#define displayExtentChangedEvent ((eventsEnum)(firstUserEvent-2)) +typedef struct displayExtentChangedDataType +{ + RectangleType oldDim; + RectangleType newDim; +} displayExtentChangedDataType; + +/*--------------------------------------------------------------------------- + * Macro to simplify getting the data out of the event structure. + * Example: + * yDiff = displayExtentChangedData(eventP)->newDim->extent.y - + * displayExtentChangedData(eventP)->oldDim->extent.y; + *--------------------------------------------------------------------------*/ +#define displayExtentChangedData(eventP) ((displayExtentChangedDataType *)(&((eventP)->data.generic))) + +/*--------------------------------------------------------------------------- + * Vga Font ID's + *--------------------------------------------------------------------------*/ +enum vgaFontID { + vga4x8FixedFont = 0x00, + vga10x16FixedFont, + vga14x22FixedFont +}; + +typedef enum vgaFontID VgaFontID; + +/*--------------------------------------------------------------------------- + * Screen and rotation modes + *--------------------------------------------------------------------------*/ +typedef enum +{ + screenModeScaleToFit = 0, + screenMode1To1, + screenModeOffset //System Use Only +} VgaScreenModeType; + +typedef enum +{ + rotateModeNone = 0, + rotateMode90, + rotateMode180, + rotateMode270 +} VgaRotateModeType; + +/*--------------------------------------------------------------------------- + * Legacy app display modes. + *--------------------------------------------------------------------------*/ +typedef enum +{ + offsetModeTopLeft = 0, + offsetModeTopCenter, + offsetModeTopRight, + offsetModeCenterLeft, + offsetModeCenterCenter, + offsetModeCenterRight, + offsetModeBottomLeft, + offsetModeBottomCenter, + offsetModeBottomRight +} VgaOffsetModeType; + +/*--------------------------------------------------------------------------- + * Font Select Types + *--------------------------------------------------------------------------*/ +typedef enum +{ + vgaFontSelectPalm = 0, + vgaFontSelectVgaText +} VgaFontSelectType; + +/*--------------------------------------------------------------------------- + * Form Modify Types + *--------------------------------------------------------------------------*/ +typedef enum +{ + vgaFormModify160To240 = 0 +} VgaFormModifyType; + +/*--------------------------------------------------------------------------- + * Vga Screen State + *--------------------------------------------------------------------------*/ +typedef struct VgaScreenStateType +{ + VgaScreenModeType mode; + VgaRotateModeType rotate; + VgaOffsetModeType offset; +} VgaScreenStateType; + +/*--------------------------------------------------------------------------- + * Vga System State + *--------------------------------------------------------------------------*/ +typedef struct VgaSystemStateType +{ + VgaScreenModeType screenMode; + Int16 offset_X; + Int16 offset_Y; + + UInt8 draw_override; + UInt8 list_draw; + UInt8 use_large_font; + UInt8 use_large_nontextfont; + + UInt8 reserved[16]; +} VgaSystemStateType; + + +#ifdef __cplusplus +extern "C" { +#endif + +#define trgMinVgaFunction 0x0200 +#define trgGetScreenMode (trgMinVgaFunction + 0) +#define trgSetScreenMode (trgMinVgaFunction + 1) + +#define trgBitmapExpandedExtent (trgMinVgaFunction + 2) +#define trgNOP (trgMinVgaFunction + 3) //Remove +#define trgWinDrawBitmapExpanded (trgMinVgaFunction + 4) + +#define trgBaseToVgaFont (trgMinVgaFunction + 5) +#define trgFontSelect (trgMinVgaFunction + 6) +#define trgGetFrmTitleHeight (trgMinVgaFunction + 7) +#define trgIsVgaFont (trgMinVgaFunction + 8) +#define trgVgaEnable (trgMinVgaFunction + 9) +#define trgVgaDisable (trgMinVgaFunction + 10) +#define trgVgaIsEnabled (trgMinVgaFunction + 11) +#define trgGetLegacyMode (trgMinVgaFunction + 12) +#define trgSetLegacyMode (trgMinVgaFunction + 13) + +#define trgTableUseBaseFont (trgMinVgaFunction + 14) + +#define trgFrmModify (trgMinVgaFunction + 15) + +#define trgVgaToBaseFont (trgMinVgaFunction + 16) + +#define trgReloadAppPrefs (trgMinVgaFunction + 17) + +#define trgSaveScreenState (trgMinVgaFunction + 18) +#define trgRestoreScreenState (trgMinVgaFunction + 19) + +#define trgRotateSelect (trgMinVgaFunction + 20) + +#define trgGetSystemState (trgMinVgaFunction + 21) + +#define trgGetFontPtr (trgMinVgaFunction + 22) +#define trgSetFontPtr (trgMinVgaFunction + 23) +#define trgGetNumVgaFonts (trgMinVgaFunction + 24) +#define trgPalmFontID (trgMinVgaFunction + 25) + +#define trgMaxVgaFunction 0x0219 + + +/******************************************************************** + * VGA API Prototypes + ********************************************************************/ + +/*--------------------------------------------------------------------------- + * Returns the current mode and rotation settings + *--------------------------------------------------------------------------*/ +extern void VgaGetScreenMode(VgaScreenModeType *mode, VgaRotateModeType *rotation) + EXT_TRAP(trgGetScreenMode); + +/*--------------------------------------------------------------------------- + * Set current screen mode. + *--------------------------------------------------------------------------*/ +extern Err VgaSetScreenMode(VgaScreenModeType mode, VgaRotateModeType rotation) + EXT_TRAP(trgSetScreenMode); + +/*--------------------------------------------------------------------------- + * Pass in non-expanded bitmap and destination, returns the X & Y extent + * the expanded bitmap. + *--------------------------------------------------------------------------*/ +extern void VgaBitmapExpandedExtent(BitmapPtr bitmapP, Coord *extentX, Coord *extentY) + EXT_TRAP(trgBitmapExpandedExtent); + +/*--------------------------------------------------------------------------- + * Draw the bitmap at 1.5 scale. This is needed for non 160x160 applications + * that need to expand existing small bitmaps. (IE Launcher) + *--------------------------------------------------------------------------*/ +extern void VgaWinDrawBitmapExpanded(BitmapPtr bitmapP, Coord x, Coord y) + EXT_TRAP(trgWinDrawBitmapExpanded); + +/*--------------------------------------------------------------------------- + * Take the Palm font and return the 1.5 scale font + *--------------------------------------------------------------------------*/ +extern FontID VgaBaseToVgaFont(FontID font) + EXT_TRAP(trgBaseToVgaFont); + +/*--------------------------------------------------------------------------- + * Take the Vga font and return the Palm font + *--------------------------------------------------------------------------*/ +extern FontID VgaVgaToBaseFont(FontID font) + EXT_TRAP(trgVgaToBaseFont); + +/*--------------------------------------------------------------------------- + * Display the TRG Select Font dialog which shows the 4 Palm text fonts + * plus the 4 equivalent TRG larger fonts. + *--------------------------------------------------------------------------*/ +extern FontID VgaFontSelect(VgaFontSelectType selectFormType, FontID fontID) + EXT_TRAP(trgFontSelect); + +/*--------------------------------------------------------------------------- + * Is font a 1.5 expanded font. + *--------------------------------------------------------------------------*/ +extern Boolean VgaIsVgaFont(FontID font) + EXT_TRAP(trgIsVgaFont); + +/*--------------------------------------------------------------------------- + * Use small Palm font when drawing tableItemStyles excluding customTableItem + * which determines its + *--------------------------------------------------------------------------*/ +extern void VgaTableUseBaseFont(TablePtr table, Boolean on) + EXT_TRAP(trgTableUseBaseFont); + +/*--------------------------------------------------------------------------- + * Return the heigth of the Titlebar. Necessary for placement of form text + * and objects + *--------------------------------------------------------------------------*/ +extern UInt16 VgaGetFrmTitleHeight(void) + EXT_TRAP(trgGetFrmTitleHeight); + +/*--------------------------------------------------------------------------- + * VgaEnable + *--------------------------------------------------------------------------*/ +extern void VgaEnable(Boolean redraw) + EXT_TRAP(trgVgaEnable); + +/*--------------------------------------------------------------------------- + * VgaDisable + *--------------------------------------------------------------------------*/ +extern void VgaDisable(Boolean redraw) + EXT_TRAP(trgVgaDisable); + +/*--------------------------------------------------------------------------- + * VgaIsEnabled + *--------------------------------------------------------------------------*/ +extern Boolean VgaIsEnabled(void) + EXT_TRAP(trgVgaIsEnabled); + +/*--------------------------------------------------------------------------- + * VgaGetLegacyMode + *--------------------------------------------------------------------------*/ +extern void VgaGetLegacyMode(VgaScreenModeType *viewMode, VgaOffsetModeType *offsetMode) + EXT_TRAP(trgGetLegacyMode); + +/*--------------------------------------------------------------------------- + * VgaSetLegacyMode + *--------------------------------------------------------------------------*/ +extern void VgaSetLegacyMode(VgaScreenModeType viewMode, VgaOffsetModeType offsetMode) + EXT_TRAP(trgSetLegacyMode); + +/*--------------------------------------------------------------------------- + * VgaFormModify + *--------------------------------------------------------------------------*/ +extern Err VgaFormModify(FormType *frmP, VgaFormModifyType type) + EXT_TRAP(trgFrmModify); + +/*--------------------------------------------------------------------------- + * VgaFormModify + * + * #define to allow the old VgaFrmModify routine. Please change your code to + * use the new VgaFormModify routine above. This #define will be removed in + * the future. + *--------------------------------------------------------------------------*/ +#define VgaFrmModify(frmP, type) (VgaFormModify((frmP, type))) + +/*--------------------------------------------------------------------------- + * VgaLoadAppPrefs + *--------------------------------------------------------------------------*/ +extern void VgaReloadAppPrefs(void) + EXT_TRAP(trgReloadAppPrefs); + +/*--------------------------------------------------------------------------- + * VgaSaveScreenState + *--------------------------------------------------------------------------*/ +extern void VgaSaveScreenState(VgaScreenStateType *state) + EXT_TRAP(trgSaveScreenState); + +/*--------------------------------------------------------------------------- + * VgaRestoreScreenState + *--------------------------------------------------------------------------*/ +extern Err VgaRestoreScreenState(VgaScreenStateType *state) + EXT_TRAP(trgRestoreScreenState); + +/*--------------------------------------------------------------------------- + * VgaRotateSelect + *--------------------------------------------------------------------------*/ +extern VgaRotateModeType VgaRotateSelect (VgaRotateModeType rotateMode) + EXT_TRAP(trgRotateSelect); + +/*--------------------------------------------------------------------------- + * VgaGetSystemState + *--------------------------------------------------------------------------*/ +extern void VgaGetSystemState(VgaSystemStateType *pState) + EXT_TRAP(trgGetSystemState); + +/*--------------------------------------------------------------------------- + * VgaGetFontPtr + *--------------------------------------------------------------------------*/ +extern Err VgaGetFontPtr(FontID font, FontPtr *fontP) + EXT_TRAP(trgGetFontPtr); + +/*--------------------------------------------------------------------------- + * VgaSetFontPtr + *--------------------------------------------------------------------------*/ +extern Err VgaSetFontPtr(FontID font, FontPtr fontP) + EXT_TRAP(trgSetFontPtr); + +/*--------------------------------------------------------------------------- + * VgaGetNumVgaFonts + *--------------------------------------------------------------------------*/ +extern UInt16 VgaGetNumVgaFonts(void) + EXT_TRAP(trgGetNumVgaFonts); + + +/*--------------------------------------------------------------------------- + * VgaPalmFontID + *--------------------------------------------------------------------------*/ +extern FontID VgaPalmFontID(VgaFontID font) + EXT_TRAP(trgPalmFontID); + +#ifdef __cplusplus +} +#endif + + +#endif // __VGA_H__ diff --git a/handera-sdk-105/include/Audio.h b/handera-sdk-105/include/Audio.h new file mode 100644 index 0000000..e425821 --- /dev/null +++ b/handera-sdk-105/include/Audio.h @@ -0,0 +1,271 @@ +/**************************************************************************** + * + * Copyright (c) 2001, TRG, All Rights Reserved + * + *--------------------------------------------------------------------------- + * FileName: + * Audio.h + * + * Description: + * Audio API definitions. + * + * + ****************************************************************************/ + +#ifndef __AUDIO_H__ +#define __AUDIO_H__ + +#include "Trg.h" + +#define TRGAudioFtrNum 5 + +/*-------------------------------------------------------------------------- + * Audio result codes + * (oemErrorClass is reserved for OEM/Licensees). + *-------------------------------------------------------------------------*/ +#define audioErrorClass (oemErrorClass | 0x500) + +#define audioErrUnimplemented (audioErrorClass | 0) // function not implemented (on this hardware) +#define audioErrBadParam (audioErrorClass | 1) // invalid parameter +#define audioErrInvalidData (audioErrorClass | 2) // bad wave data +#define audioErrUnsupportedFormat (audioErrorClass | 3) // unsupported play/record format + +/*--------------------------------------------------------------------------- + * Extension Installed + *--------------------------------------------------------------------------*/ +#define _TRGAudioFeaturePresent(version) \ + (Boolean)(FtrGet(TRGSysFtrID, TRGAudioFtrNum, version) == 0) + + +/*--------------------------------------------------------------------------- + * Format structure for playing and recording PWM data + *--------------------------------------------------------------------------*/ +typedef struct AudioFormatType +{ + UInt16 samplesPerSecond; // TRGpro < 33kHz, HandEra 330 <= 44kHz + UInt16 bitsPerSample; // only 8 bit is supported + UInt16 channels; // only 1 channel is supported + UInt32 data_size; // only needed for AudioOpenRawData() in play mode. + UInt8 reserved[4]; +} AudioFormatType; + +/*--------------------------------------------------------------------------- + * enum for audioModeType + *--------------------------------------------------------------------------*/ +typedef enum AudioModeType +{ + audioPlayMode, + audioRecordMode +} AudioModeType; + +/*--------------------------------------------------------------------------- + * Defines for AudGetSupportedFeatures features bitmap + *--------------------------------------------------------------------------*/ +#define audioFtrPlayWave 0x0001 +#define audioFtrAdjVolume 0x0002 +#define audioFtrDTMF 0x0004 +#define audioFtrRecordWave 0x0008 + +/*--------------------------------------------------------------------------- + * min and max volume levels + *--------------------------------------------------------------------------*/ +#define audioVolumeMax 255 +#define audioVolumeMin 0 + +/*--------------------------------------------------------------------------- + * wave playing progress events + *--------------------------------------------------------------------------*/ +#define audioProgressEvent ((eventsEnum)(firstUserEvent-1)) + +// progress is stored in the following fields of a generic eventType +// datum[0]: percent complete +// datum[1]: minutes +// datum[2]: seconds +// datum[3]: 1/100ths of second +typedef struct AudioProgressType +{ + eventsEnum eType; + Boolean reserved; + UInt8 percent; + Int16 minutes; + Int16 seconds; +} AudioProgressType; + + +#define trgMinAudFunction 0x0500 +#define trgAudGetSupportedFeatures (trgMinAudFunction + 0) +#define trgAudGetMasterVolume (trgMinAudFunction + 1) +#define trgAudSetMasterVolume (trgMinAudFunction + 2) +#define trgAudGetMute (trgMinAudFunction + 3) +#define trgAudSetMute (trgMinAudFunction + 4) +#define trgAudPlayDTMFChar (trgMinAudFunction + 5) +#define trgAudPlayDTMFStr (trgMinAudFunction + 6) +#define trgAudPlayData (trgMinAudFunction + 7) +#define trgAudRecordData (trgMinAudFunction + 8) +#define trgAudPause (trgMinAudFunction + 9) +#define trgAudOpenWaveOld (trgMinAudFunction + 10) +#define trgAudCloseWave (trgMinAudFunction + 11) +#define trgAudVolumeDlg (trgMinAudFunction + 12) +#define trgAudSeek (trgMinAudFunction + 13) +#define trgAudSeekPercent (trgMinAudFunction + 14) +#define trgAudTell (trgMinAudFunction + 15) +#define trgAudTellPercent (trgMinAudFunction + 16) +#define trgAudOpenRawDataOld (trgMinAudFunction + 17) +#define trgAudCloseRawData (trgMinAudFunction + 18) +#define trgAudCreateWave (trgMinAudFunction + 19) +#define trgAudCreateRawData (trgMinAudFunction + 20) +#define trgAudOpenWave (trgMinAudFunction + 21) +#define trgAudOpenRawData (trgMinAudFunction + 22) +#define trgMaxAudFunction (trgMinAudFunction + 22) + +/******************************************************************** + * Audio API Prototypes + ********************************************************************/ + +/*--------------------------------------------------------------------------- + * function prototypes for callbacks + *--------------------------------------------------------------------------*/ +typedef Err (*AudioReadProcPtr) + (void *dataP, UInt32 offset, UInt32 *sizeP, void *userDataP); + +typedef Err (*AudioWriteProcPtr) + (void *dataP, UInt32 offset, UInt32 *sizeP, void *userDataP); + +#ifdef __cplusplus +extern "C" { +#endif + +/*--------------------------------------------------------------------------- + * get features support on this hardware + *--------------------------------------------------------------------------*/ +extern Err AudioGetSupportedFeatures(UInt32 *features) + EXT_TRAP(trgAudGetSupportedFeatures); + +/*--------------------------------------------------------------------------- + * Display volume dlg (pass NULL for default title) + *--------------------------------------------------------------------------*/ +extern Err AudioVolumeDlg(Char *title) + EXT_TRAP(trgAudVolumeDlg); + +/*--------------------------------------------------------------------------- + * Get master volume (0-255) + *--------------------------------------------------------------------------*/ +extern Err AudioGetMasterVolume(UInt8 *volume) + EXT_TRAP(trgAudGetMasterVolume); + +/*--------------------------------------------------------------------------- + * Set master volume (0-255) + *--------------------------------------------------------------------------*/ +extern Err AudioSetMasterVolume(UInt8 volume) + EXT_TRAP(trgAudSetMasterVolume); + +/*--------------------------------------------------------------------------- + * Get mute status + *--------------------------------------------------------------------------*/ +extern Err AudioGetMute(Boolean *mute) + EXT_TRAP(trgAudGetMute); + +/*--------------------------------------------------------------------------- + * Set mute status + *--------------------------------------------------------------------------*/ +extern Err AudioSetMute(Boolean mute) + EXT_TRAP(trgAudSetMute); + +/*--------------------------------------------------------------------------- + * Play a DTMF tone + *--------------------------------------------------------------------------*/ +extern Err AudioPlayDTMFChar(char ascChar, Int16 toneLength) + EXT_TRAP(trgAudPlayDTMFChar); + +/*--------------------------------------------------------------------------- + * Play a DTMF sequence + *--------------------------------------------------------------------------*/ +extern Err AudioPlayDTMFStr(char *ascStr, Int16 toneLength, Int16 toneGap) + EXT_TRAP(trgAudPlayDTMFStr); + + +/*--------------------------------------------------------------------------- + * Open a wave file and write out the header information and prepare to + * record new data + * NOTE: only one wave file may be open at a time + *--------------------------------------------------------------------------*/ +extern Err AudioCreateWave(AudioFormatType *dataFormat, + AudioWriteProcPtr writeData, + void *userData) + EXT_TRAP(trgAudCreateWave); + +/*--------------------------------------------------------------------------- + * Open a wave file and read in the header information and prepare to play + * the data + * NOTE: only one wave file may be open at a time + *--------------------------------------------------------------------------*/ +extern Err AudioOpenWave(AudioFormatType *dataFormat, + AudioReadProcPtr getData, + void *userData) + EXT_TRAP(trgAudOpenWave); + +/*--------------------------------------------------------------------------- + * Close the file and update the header information if needed. + *--------------------------------------------------------------------------*/ +extern Err AudioCloseWave(void) + EXT_TRAP(trgAudCloseWave); + +/*--------------------------------------------------------------------------- + * Play PWM/Wave data + *--------------------------------------------------------------------------*/ +extern Err AudioPlayData(void) + EXT_TRAP(trgAudPlayData); + +/*--------------------------------------------------------------------------- + * Record PWM data + *--------------------------------------------------------------------------*/ +extern Err AudioRecordData(void) + EXT_TRAP(trgAudRecordData); + +/*--------------------------------------------------------------------------- + * Stop/Pause play or record + *--------------------------------------------------------------------------*/ +extern Err AudioPause(void) + EXT_TRAP(trgAudPause); + +extern Err AudioSeek(UInt32 tenthsOfSeconds) + EXT_TRAP(trgAudSeek); + +extern Err AudioSeekPercent(UInt16 percent) + EXT_TRAP(trgAudSeekPercent); + +extern Err AudioTell(UInt32 *tenthsOfSeconds) + EXT_TRAP(trgAudTell); + +extern Err AudioTellPercent(UInt16 *percent) + EXT_TRAP(trgAudTellPercent); + +extern Err AudioCreateRawData(AudioFormatType *dataFormat, + AudioWriteProcPtr writeData, + void *userData) + EXT_TRAP(trgAudCreateRawData); + +extern Err AudioOpenRawData(AudioFormatType *dataFormat, + AudioReadProcPtr getData, + void *userData) + EXT_TRAP(trgAudOpenRawData); + +extern Err AudioCloseRawData(void) + EXT_TRAP(trgAudCloseRawData); + +extern Err AudioOpenWaveOld(AudioModeType mode, AudioFormatType *dataFormat, + AudioReadProcPtr getData, AudioWriteProcPtr writeData, + void *userData) + EXT_TRAP(trgAudOpenWaveOld); + +extern Err AudioOpenRawDataOld(AudioModeType mode, AudioFormatType *dataFormat, + AudioReadProcPtr getData, AudioWriteProcPtr writeData, + void *userData) + EXT_TRAP(trgAudOpenRawDataOld); + +#ifdef __cplusplus +} +#endif + + +#endif // __AUDIO_H__ diff --git a/handera-sdk-105/include/HandEra.r b/handera-sdk-105/include/HandEra.r new file mode 100644 index 0000000..371e069 --- /dev/null +++ b/handera-sdk-105/include/HandEra.r @@ -0,0 +1,29 @@ +/*********************************************************************** + * + * Copyright (c) 1999-2001, TRG, All Rights Reserved + * + * PROJECT: HandEra 330 + * + * FILE: HandEra.r + * + * DESCRIPTION: + * + * AUTHOR: John Ehm + * + * DATE: 01/17/01 + * + **********************************************************************/ + + +type 'sKst' { + //Currently no data is stored in resource, need dummy otherwise + //resource is not linked in + unsigned longint; +}; + + +resource 'sKst' (1000, "HandEra Aware") +{ + 0x00000000; + +}; diff --git a/handera-sdk-105/include/Silk.h b/handera-sdk-105/include/Silk.h new file mode 100644 index 0000000..f39785f --- /dev/null +++ b/handera-sdk-105/include/Silk.h @@ -0,0 +1,181 @@ +/**************************************************************************** + * + * Copyright (c) 2001, TRG, All Rights Reserved + * + *--------------------------------------------------------------------------- + * FileName: + * Silk.h + * + * Description: + * Silkscreen API definitions. + * + * + ****************************************************************************/ + +#ifndef __SILK_H__ +#define __SILK_H__ + +#include "Trg.h" + +#define TRGSilkFtrNum 7 + + +/*--------------------------------------------------------------------------- + * NotifyMgr: Notification of Silk minimize/maximize events + * NOTE: If your app is form based, it is much easier to + * handle the qvgaChangedEvent in your form handle event instead. + *--------------------------------------------------------------------------*/ +#define trgNotifySilkEvent 'slkx' +typedef struct +{ + Boolean silk_minimized; +} silkEventType; + + +/*--------------------------------------------------------------------------- + * Extension Installed + *--------------------------------------------------------------------------*/ +#define _TRGSilkFeaturePresent(version) \ + (Boolean)(FtrGet(TRGSysFtrID, TRGSilkFtrNum, version) == 0) + +/*--------------------------------------------------------------------------- + * Silk API result codes + * (oemErrorClass is reserved for Palm licensees). + *--------------------------------------------------------------------------*/ +#define silkErrorClass (oemErrorClass | 0x700) +#define silkErrBadParam (silkErrorClass | 0) // invalid parameter + + +#ifdef __cplusplus +extern "C" { +#endif + +#define trgMinSilkFunction 0x0700 + +#define trgGetSilkWindow (trgMinSilkFunction + 0) +#define trgGetSilkTemplate (trgMinSilkFunction + 1) +#define trgSilkRestoreDefaultTemplate (trgMinSilkFunction + 2) +#define trgDrawSilkWindow (trgMinSilkFunction + 3) +#define trgEraseSilkWindow (trgMinSilkFunction + 4) +#define trgGetAreas (trgMinSilkFunction + 5) +#define trgSetAreas (trgMinSilkFunction + 6) +#define trgGetButtons (trgMinSilkFunction + 7) +#define trgSetButtons (trgMinSilkFunction + 8) +#define trgGetGraffitiPersistence (trgMinSilkFunction + 9) +#define trgSetGraffitiPersistence (trgMinSilkFunction + 10) +#define trgSetSilkTemplate (trgMinSilkFunction + 11) +#define trgGetButtonListSize (trgMinSilkFunction + 12) +#define trgSilkWindowShown (trgMinSilkFunction + 13) +#define trgSetPenEnabled (trgMinSilkFunction + 14) +#define trgGetPenEnabled (trgMinSilkFunction + 15) + +#define trgMaxSilkFunction (trgMinSilkFunction + 15) + +/******************************************************************** + * Silk API Prototypes + ********************************************************************/ + +/*--------------------------------------------------------------------------- + * Show the Silk window. + *--------------------------------------------------------------------------*/ +extern void SilkMaximizeWindow(void) + EXT_TRAP(trgDrawSilkWindow); + +/*--------------------------------------------------------------------------- + * Hide the silk window. + *--------------------------------------------------------------------------*/ +extern void SilkMinimizeWindow(void) + EXT_TRAP(trgEraseSilkWindow); + +/*--------------------------------------------------------------------------- + * Is the silk window maximized or minimized?. + *--------------------------------------------------------------------------*/ +extern Boolean SilkWindowMaximized(void) + EXT_TRAP(trgSilkWindowShown); + +/*--------------------------------------------------------------------------- + * Return a WinHandle to the Silk Template to allow drawing directly to the + * onscreen window + *--------------------------------------------------------------------------*/ +extern WinHandle SilkGetWindow(void) + EXT_TRAP(trgGetSilkWindow); + +/*--------------------------------------------------------------------------- + * Returns pointers to the template bitmaps + *--------------------------------------------------------------------------*/ +extern void SilkGetTemplateBitmaps(BitmapPtr *maxSilkTemplate, BitmapPtr *selectedMaxSilkTemplate, + BitmapPtr *minSilkTemplate, BitmapPtr *selectedMinSilkTemplate) + EXT_TRAP(trgGetSilkTemplate); + +/*--------------------------------------------------------------------------- + * Provide bitmaps for the silk template. + *--------------------------------------------------------------------------*/ +extern Err SilkSetTemplateBitmaps(BitmapPtr maxSilkTemplate, BitmapPtr selectedMaxSilkTemplate, + BitmapPtr minSilkTemplate, BitmapPtr selectedMinSilkTemplate) + EXT_TRAP(trgSetSilkTemplate); + +/*--------------------------------------------------------------------------- + * Restore the Silk Template to default. + *--------------------------------------------------------------------------*/ +extern Err SilkRestoreDefaultTemplates(void) + EXT_TRAP(trgSilkRestoreDefaultTemplate); + +/*--------------------------------------------------------------------------- + * Get the silk screen button list size. Caller should call this first, + * allocate a buffer of this size, then call SilkGetButtons(). + *--------------------------------------------------------------------------*/ +extern UInt16 SilkGetButtonListSize(Boolean maximized) + EXT_TRAP(trgGetButtonListSize); + +/*--------------------------------------------------------------------------- + * Get the silk screen button list + *--------------------------------------------------------------------------*/ +extern Err SilkGetButtonList(PenBtnListType *buttonList, Boolean maximized) + EXT_TRAP(trgGetButtons); + +/*--------------------------------------------------------------------------- + * Set the silk screen button list + *--------------------------------------------------------------------------*/ +extern Err SilkSetButtonList(PenBtnListType *buttonList, Boolean maximized) + EXT_TRAP(trgSetButtons); + +/*--------------------------------------------------------------------------- + * Get the silk screen alpha and numeric areas + *--------------------------------------------------------------------------*/ +extern Err SilkGetAreas(RectangleType *alphaEntry, RectangleType *numericEntry) + EXT_TRAP(trgGetAreas); + +/*--------------------------------------------------------------------------- + * Set the silk screen alpha and numeric areas + *--------------------------------------------------------------------------*/ +extern Err SilkSetAreas(RectangleType *alphaEntry, RectangleType *numericEntry) + EXT_TRAP(trgSetAreas); + +/*--------------------------------------------------------------------------- + * Get number of timer ticks graffiti remains on the silk area + *--------------------------------------------------------------------------*/ +extern UInt32 SilkGetGraffitiPersistence(void) + EXT_TRAP(trgGetGraffitiPersistence); + +/*--------------------------------------------------------------------------- + * Set number of timer ticks graffiti remains on the silk area + *--------------------------------------------------------------------------*/ +extern void SilkSetGraffitiPersistence(UInt32 ticks) + EXT_TRAP(trgSetGraffitiPersistence); + +/*--------------------------------------------------------------------------- + * System use only + *--------------------------------------------------------------------------*/ +extern void SilkSetPenEnabled(Boolean enabled) + EXT_TRAP(trgSetPenEnabled); + + +extern Boolean SilkGetPenEnabled(void) + EXT_TRAP(trgGetPenEnabled); + +#ifdef __cplusplus +} +#endif + + +#endif // __SILK_H__ diff --git a/handera-sdk-105/include/Trg.h b/handera-sdk-105/include/Trg.h new file mode 100644 index 0000000..c220ea8 --- /dev/null +++ b/handera-sdk-105/include/Trg.h @@ -0,0 +1,56 @@ +/*********************************************************************** + * + * Copyright (c) 2001 TRG, All Rights Reserved + * + * FileName: + * TRG.h + * + * Description: + * + * + * History: + * 7-10-00 -- original version + * + **********************************************************************/ +#ifndef _TRG_H_ +#define _TRG_H_ + +#include +#include + +#define TRGSysFtrID 'TRG ' + +#ifdef __GNUC__ + +#define _TRG_CALL_WITH_16BIT_SELECTOR(table, vector, selector)\ + __attribute__ ((__callseq__ (\ + "move.w #" _Str(selector) ",%%d2; "\ + "trap #" _Str(table) "; dc.w " _Str(vector) ))) + +#elif defined (__MWERKS__) /* The equivalent in CodeWarrior syntax */ + +#define _TRG_CALL_WITH_16BIT_SELECTOR(table, vector, selector) \ + = { 0x343C, selector, 0x4E40 + table, vector } + +#endif + +#define TRG_TRAP(sel) \ + _TRG_CALL_WITH_16BIT_SELECTOR(_SYSTEM_TABLE, sysTrapOEMDispatch, sel) + +#ifdef BUILDING_EXTENSION + #define EXT_TRAP(x) +#else + #define EXT_TRAP(x) TRG_TRAP(x) +#endif + + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + + +#endif diff --git a/handera-sdk-105/include/TrgChars.h b/handera-sdk-105/include/TrgChars.h new file mode 100644 index 0000000..1afbad6 --- /dev/null +++ b/handera-sdk-105/include/TrgChars.h @@ -0,0 +1,53 @@ +/******************************************************************* + * + * Copyright (c) 2001 TRG, All Rights Reserved + * + * FileName: + * TRGChars.h + * + * Description: + * Extra character and keyboard bitmap definitions used + * on TRG devices. + * + * History: + * 11-21-00 -- original version + * + ********************************************************************/ +#ifndef __TRG_CHARS_H__ +#define __TRG_CHARS_H__ + +#define TRGKeyFtrNum 20 + +// this feature provides a bitmap of the extra keys that are available +// on this unit that may be returned from KeyCurrentState() +#define _TRGKeyFeaturePresent(keymapPtr) \ + (Boolean)(FtrGet(TRGSysFtrID, TRGKeyFtrNum, keymapPtr) == 0) + +/*------------------------------------------------------------------- + * Additional definition of bit field returned from KeyCurrentState, + * see KeyMgr.h + *------------------------------------------------------------------*/ +#define keyBitJogUp 0x1000 +#define keyBitJogDown 0x2000 +#define keyBitJogPush 0x4000 +#define keyBitAux 0x8000 + +/*------------------------------------------------------------------- + * Additional character definitions corresponding to additional hard + * buttons on StarKist. See Chars.h + *------------------------------------------------------------------*/ +#define vchrTrgJogUp (vchrCFlashMin + 4) +#define vchrTrgJogDown (vchrCFlashMin + 5) +#define vchrTrgJogPush (vchrCFlashMin + 6) +#define vchrTrgAux (vchrCFlashMin + 7) + +/*------------------------------------------------------------------- + * Additional virtual characters for extra silk buttons on StarKist + * See Chars.h + *------------------------------------------------------------------*/ +#define vchrTRGVolume (vchrCFlashMin + 3) +#define vchrSilkToggle (vchrCFlashMin + 10) + + +#endif // #ifndef __TRG_CHARS_H__ + diff --git a/handera-sdk-105/include/TrgRsc.h b/handera-sdk-105/include/TrgRsc.h new file mode 100644 index 0000000..5261b41 --- /dev/null +++ b/handera-sdk-105/include/TrgRsc.h @@ -0,0 +1,27 @@ +/******************************************************************* + * + * Copyright (c) 2001 TRG, All Rights Reserved + * + * FileName: + * TRGRsc.h + * + * Description: + * Resource defintions for the HandEra 330 + * + * History: + * 3-20-00 -- original version + * + ********************************************************************/ +#ifndef __TRG_RSC_H__ +#define __TRG_RSC_H__ + + +#define vgaAppIconID 2000 +#define vgaAppSmallIconID 2001 +#define vgaInvertedIconID 2002 + +#define vgaResourceDbType 'strt' + + +#endif // #ifndef __TRG_RSC_H__ + diff --git a/handera-sdk-105/include/Vga.h b/handera-sdk-105/include/Vga.h new file mode 100644 index 0000000..62f63e4 --- /dev/null +++ b/handera-sdk-105/include/Vga.h @@ -0,0 +1,310 @@ +/**************************************************************************** + * + * Copyright (c) 2001, TRG, All Rights Reserved + * + *--------------------------------------------------------------------------- + * FileName: + * Vga.h + * + * Description: + * VGA API definitions. + * + * + ****************************************************************************/ + +#ifndef __VGA_H__ +#define __VGA_H__ + +#include "Trg.h" + +#define TRGVgaFtrNum 2 + +/*-------------------------------------------------------------------------- + * Vga result codes + * (oemErrorClass is reserved for Palm licensees). + *-------------------------------------------------------------------------*/ +#define vgaErrorClass (oemErrorClass | 0x200) + +#define vgaErrUnimplemented (vgaErrorClass | 0) // function not implemented (on this hardware) +#define vgaErrBadParam (vgaErrorClass | 1) // invalid parameter +#define vgaErrModeUnsupported (vgaErrorClass | 2) // does not support screen mode +#define vgaErrScreenLocked (vgaErrorClass | 3) // ??? + +/*--------------------------------------------------------------------------- + * Extension Installed + *--------------------------------------------------------------------------*/ +#define _TRGVGAFeaturePresent(versionPtr) \ + (Boolean)(FtrGet(TRGSysFtrID, TRGVgaFtrNum, versionPtr) == 0) + + +/*--------------------------------------------------------------------------- + * Notification that the screen area changed (silk minimize/maximized, rotation) + *--------------------------------------------------------------------------*/ +#define displayExtentChangedEvent ((eventsEnum)(firstUserEvent-2)) +typedef struct displayExtentChangedDataType +{ + RectangleType oldDim; + RectangleType newDim; +} displayExtentChangedDataType; + +/*--------------------------------------------------------------------------- + * Macro to simplify getting the data out of the event structure. + * Example: + * yDiff = displayExtentChangedData(eventP)->newDim->extent.y - + * displayExtentChangedData(eventP)->oldDim->extent.y; + *--------------------------------------------------------------------------*/ +#define displayExtentChangedData(eventP) ((displayExtentChangedDataType *)(&((eventP)->data.generic))) + + + + +/*--------------------------------------------------------------------------- + * Screen and rotation modes + *--------------------------------------------------------------------------*/ +typedef enum +{ + screenModeScaleToFit = 0, + screenMode1To1, + screenModeOffset //System Use Only +} VgaScreenModeType; + +typedef enum +{ + rotateModeNone = 0, + rotateMode90, + rotateMode180, + rotateMode270 +} VgaRotateModeType; + +/*--------------------------------------------------------------------------- + * Legacy app display modes. + *--------------------------------------------------------------------------*/ +typedef enum +{ + offsetModeTopLeft = 0, + offsetModeTopCenter, + offsetModeTopRight, + offsetModeCenterLeft, + offsetModeCenterCenter, + offsetModeCenterRight, + offsetModeBottomLeft, + offsetModeBottomCenter, + offsetModeBottomRight +} VgaOffsetModeType; + +/*--------------------------------------------------------------------------- + * Font Select Types + *--------------------------------------------------------------------------*/ +typedef enum +{ + vgaFontSelectPalm = 0, + vgaFontSelectVgaText +} VgaFontSelectType; + +/*--------------------------------------------------------------------------- + * Form Modify Types + *--------------------------------------------------------------------------*/ +typedef enum +{ + vgaFormModify160To240 = 0 +} VgaFormModifyType; + +/*--------------------------------------------------------------------------- + * Vga Screen State + *--------------------------------------------------------------------------*/ +typedef struct VgaScreenStateType +{ + VgaScreenModeType mode; + VgaRotateModeType rotate; + VgaOffsetModeType offset; +} VgaScreenStateType; + +#ifdef __cplusplus +extern "C" { +#endif + +#define trgMinVgaFunction 0x0200 +#define trgGetScreenMode (trgMinVgaFunction + 0) +#define trgSetScreenMode (trgMinVgaFunction + 1) + +#define trgBitmapExpandedExtent (trgMinVgaFunction + 2) +#define trgNOP (trgMinVgaFunction + 3) //Remove +#define trgWinDrawBitmapExpanded (trgMinVgaFunction + 4) + +#define trgBaseToVgaFont (trgMinVgaFunction + 5) +#define trgFontSelect (trgMinVgaFunction + 6) +#define trgGetFrmTitleHeight (trgMinVgaFunction + 7) +#define trgIsVgaFont (trgMinVgaFunction + 8) +#define trgVgaEnable (trgMinVgaFunction + 9) +#define trgVgaDisable (trgMinVgaFunction + 10) +#define trgVgaIsEnabled (trgMinVgaFunction + 11) +#define trgGetLegacyMode (trgMinVgaFunction + 12) +#define trgSetLegacyMode (trgMinVgaFunction + 13) + +#define trgTableUseBaseFont (trgMinVgaFunction + 14) + +#define trgFrmModify (trgMinVgaFunction + 15) + +#define trgVgaToBaseFont (trgMinVgaFunction + 16) + +#define trgReloadAppPrefs (trgMinVgaFunction + 17) + +#define trgSaveScreenState (trgMinVgaFunction + 18) +#define trgRestoreScreenState (trgMinVgaFunction + 19) + +#define trgRotateSelect (trgMinVgaFunction + 20) + +#define trgMaxVgaFunction 0x0214 + + +/******************************************************************** + * VGA API Prototypes + ********************************************************************/ + +/*--------------------------------------------------------------------------- + * Returns the current mode and rotation settings + *--------------------------------------------------------------------------*/ +extern void VgaGetScreenMode(VgaScreenModeType *mode, VgaRotateModeType *rotation) + EXT_TRAP(trgGetScreenMode); + +/*--------------------------------------------------------------------------- + * Set current screen mode. + *--------------------------------------------------------------------------*/ +extern Err VgaSetScreenMode(VgaScreenModeType mode, VgaRotateModeType rotation) + EXT_TRAP(trgSetScreenMode); + +/*--------------------------------------------------------------------------- + * Pass in non-expanded bitmap and destination, returns the X & Y extent + * the expanded bitmap. + *--------------------------------------------------------------------------*/ +extern void VgaBitmapExpandedExtent(BitmapPtr bitmapP, Coord *extentX, Coord *extentY) + EXT_TRAP(trgBitmapExpandedExtent); + +/*--------------------------------------------------------------------------- + * Draw the bitmap at 1.5 scale. This is needed for non 160x160 applications + * that need to expand existing small bitmaps. (IE Launcher) + *--------------------------------------------------------------------------*/ +extern void VgaWinDrawBitmapExpanded(BitmapPtr bitmapP, Coord x, Coord y) + EXT_TRAP(trgWinDrawBitmapExpanded); + +/*--------------------------------------------------------------------------- + * Take the Palm font and return the 1.5 scale font + *--------------------------------------------------------------------------*/ +extern FontID VgaBaseToVgaFont(FontID font) + EXT_TRAP(trgBaseToVgaFont); + +/*--------------------------------------------------------------------------- + * Take the Vga font and return the Palm font + *--------------------------------------------------------------------------*/ +extern FontID VgaVgaToBaseFont(FontID font) + EXT_TRAP(trgVgaToBaseFont); + +/*--------------------------------------------------------------------------- + * Display the TRG Select Font dialog which shows the 4 Palm text fonts + * plus the 4 equivalent TRG larger fonts. + *--------------------------------------------------------------------------*/ +extern FontID VgaFontSelect(VgaFontSelectType selectFormType, FontID fontID) + EXT_TRAP(trgFontSelect); + +/*--------------------------------------------------------------------------- + * Is font a 1.5 expanded font. + *--------------------------------------------------------------------------*/ +extern Boolean VgaIsVgaFont(FontID font) + EXT_TRAP(trgIsVgaFont); + +/*--------------------------------------------------------------------------- + * Use small Palm font when drawing tableItemStyles excluding customTableItem + * which determines its + *--------------------------------------------------------------------------*/ +extern void VgaTableUseBaseFont(TablePtr table, Boolean on) + EXT_TRAP(trgTableUseBaseFont); + +/*--------------------------------------------------------------------------- + * Return the heigth of the Titlebar. Necessary for placement of form text + * and objects + *--------------------------------------------------------------------------*/ +extern UInt16 VgaGetFrmTitleHeight(void) + EXT_TRAP(trgGetFrmTitleHeight); + +/*--------------------------------------------------------------------------- + * VgaEnable + *--------------------------------------------------------------------------*/ +extern void VgaEnable(Boolean redraw) + EXT_TRAP(trgVgaEnable); + +/*--------------------------------------------------------------------------- + * VgaDisable + *--------------------------------------------------------------------------*/ +extern void VgaDisable(Boolean redraw) + EXT_TRAP(trgVgaDisable); + +/*--------------------------------------------------------------------------- + * VgaIsEnabled + *--------------------------------------------------------------------------*/ +extern Boolean VgaIsEnabled(void) + EXT_TRAP(trgVgaIsEnabled); + +/*--------------------------------------------------------------------------- + * VgaGetLegacyMode + *--------------------------------------------------------------------------*/ +extern void VgaGetLegacyMode(VgaScreenModeType *viewMode, VgaOffsetModeType *offsetMode) + EXT_TRAP(trgGetLegacyMode); + +/*--------------------------------------------------------------------------- + * VgaSetLegacyMode + *--------------------------------------------------------------------------*/ +extern void VgaSetLegacyMode(VgaScreenModeType viewMode, VgaOffsetModeType offsetMode) + EXT_TRAP(trgSetLegacyMode); + +/*--------------------------------------------------------------------------- + * VgaFormModify + *--------------------------------------------------------------------------*/ +extern Err VgaFormModify(FormType *frmP, VgaFormModifyType type) + EXT_TRAP(trgFrmModify); + +/*--------------------------------------------------------------------------- + * VgaFormModify + * + * #define to allow the old VgaFrmModify routine. Please change your code to + * use the new VgaFormModify routine above. This #define will be removed in + * the future. + *--------------------------------------------------------------------------*/ +#define VgaFrmModify(frmP, type) VgaFormModify(frmP, type) + +/*--------------------------------------------------------------------------- + * VgaLoadAppPrefs + *--------------------------------------------------------------------------*/ +extern void VgaReloadAppPrefs(void) + EXT_TRAP(trgReloadAppPrefs); + +/*--------------------------------------------------------------------------- + * VgaSaveScreenState + *--------------------------------------------------------------------------*/ +extern void VgaSaveScreenState(VgaScreenStateType *state) + EXT_TRAP(trgSaveScreenState); + +/*--------------------------------------------------------------------------- + * VgaRestoreScreenState + *--------------------------------------------------------------------------*/ +extern Err VgaRestoreScreenState(VgaScreenStateType *state) + EXT_TRAP(trgRestoreScreenState); + +/*--------------------------------------------------------------------------- + * VgaRestoreScreenState + *--------------------------------------------------------------------------*/ +extern Err VgaRestoreScreenState(VgaScreenStateType *state) + EXT_TRAP(trgRestoreScreenState); + +/*--------------------------------------------------------------------------- + * VgaRotateSelect + *--------------------------------------------------------------------------*/ +extern VgaRotateModeType VgaRotateSelect (VgaRotateModeType rotateMode) + EXT_TRAP(trgRotateSelect); + + +#ifdef __cplusplus +} +#endif + + +#endif // __VGA_H__ diff --git a/handera-sdk-105/include/power.h b/handera-sdk-105/include/power.h new file mode 100644 index 0000000..e9c1f4e --- /dev/null +++ b/handera-sdk-105/include/power.h @@ -0,0 +1,26 @@ +/**************************************************************************** + * + * Copyright (c) 2001, TRG, All Rights Reserved + * + *--------------------------------------------------------------------------- + * FileName: + * Power.h + * + * Description: + * Power status. + * + * + ****************************************************************************/ + +#ifndef __POWER_H__ +#define __POWER_H__ + +/*------------------------------------------------------------------------ + * Bits returned by HwrDockStatus() + *----------------------------------------------------------------------*/ +#define hwrDockStatusCharging 0x0008 // internal power cells are recharging + +UInt16 HwrDockStatus(void) + SYS_TRAP(sysTrapHwrDockStatus); + +#endif //#ifndef __POWER_H__