📄 address.c
字号:
/******************************************************************************
*
* Copyright (c) 1995-2003 PalmSource, Inc. All rights reserved.
*
* File: Address.c
*
* Release: Palm OS 5 SDK (68K) R3.
*
* Description:
* This is the Address Book application's main module. This module
* starts the application, dispatches events, and stops
* the application.
*
*****************************************************************************/
#include "Address.h"
#include "AddrList.h"
#include "AddrView.h"
#include "AddrEdit.h"
#include "AddrNote.h"
#include "AddrTools.h"
#include "AddrDetails.h"
#include "AddrCustom.h"
#include "AddrDialList.h"
#include "AddressTransfer.h"
#include "AddressLookup.h"
#include "AddrPrefs.h"
#include "AddressAutoFill.h"
#include "AddressRsc.h"
#include <Find.h>
#include <NotifyMgr.h>
#include <ErrorMgr.h>
#include <TimeMgr.h>
#include <KeyMgr.h>
#include <Menu.h>
#include <UIResources.h>
#include <SysEvtMgr.h>
/***********************************************************************
*
* Defines
*
***********************************************************************/
// Time to depress the app's button to send a business card
#define AppButtonPushTimeout (sysTicksPerSecond)
/***********************************************************************
*
* Global variables
*
***********************************************************************/
DmOpenRef AddrDB = NULL;
privateRecordViewEnum PrivateRecordVisualStatus;
Char CategoryName [dmCategoryLength];
UInt16 TopVisibleRecord = 0;
UInt16 TopVisibleFieldIndex;
UInt16 EditFieldPosition;
UInt16 CurrentRecord = noRecord;
UInt16 ListViewSelectThisRecord = noRecord; // This must
// be set whenever we leave a
// dialog because a frmSaveEvent
// happens whenever the focus is
// lost in the EditView and then
// a find and goto can happen
// causing a wrong selection to
// be used.
Boolean SortByCompany;
UInt16 PriorAddressFormID; // Used for NoteView
// These are used for controlling the display of the duplicated address records.
UInt16 NumCharsToHilite = 0;
UInt16 EditRowIDWhichHadFocus;
UInt16 EditLabelColumnWidth = 0;
UInt16 RecordLabelColumnWidth = 0;
Char * UnnamedRecordStringPtr = 0;
MemHandle UnnamedRecordStringH = 0;
Boolean RecordNeededAfterEditView;
// The following global variable are saved to a state file.
UInt16 CurrentCategory = dmAllCategories;
Boolean EnableTapDialing = false; // tap dialing is not enabled by default
Boolean ShowAllCategories = true;
Boolean SaveBackup = true;
Boolean RememberLastCategory = false;
FontID NoteFont = stdFont;
FontID AddrListFont = stdFont;
FontID AddrRecordFont = largeBoldFont;
FontID AddrEditFont = largeBoldFont;
UInt32 BusinessCardRecordID = dmUnusedRecordID;
// For business card beaming
UInt32 TickAppButtonPushed;
// Valid after PrvAppStart
WChar PhoneLabelLetters[numPhoneLabels];
Boolean DialerPresentChecked;
Boolean DialerPresent;
// For business card beaming
static UInt16 AppButtonPushed = nullChr;
static UInt16 AppButtonPushedModifiers = 0;
static Boolean BusinessCardSentForThisButtonPress = false;
/***********************************************************************
*
* Internal Functions
*
***********************************************************************/
static UInt32 PrvAppPilotMain (UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags);
static Err PrvAppStart(void);
static void PrvAppStop(void);
static void PrvAppEventLoop (void);
static Boolean PrvAppHandleKeyDown (EventType * event);
static Boolean PrvAppHandleEvent (EventType * event);
static void PrvAppSearch(FindParamsPtr findParams);
static void PrvAppGoToItem (GoToParamsPtr goToParams, Boolean launchingApp);
static void PrvAppHandleSync(void);
static Boolean PrvAppLaunchCmdDatabaseInit(DmOpenRef dbP);
/***********************************************************************
*
* FUNCTION: PilotMain
*
* DESCRIPTION: This is the main entry point for the Address
* application.
*
* PARAMETERS: nothing
*
* RETURNED: nothing
*
* NOTE: We need to create a branch island to PilotMain in order to
* successfully link this application for the device.
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 7/24/95 Initial Revision
*
***********************************************************************/
UInt32 PilotMain (UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
return PrvAppPilotMain(cmd, cmdPBP, launchFlags);
}
#pragma mark -
/***********************************************************************
*
* FUNCTION: PrvAppPilotMain
*
* DESCRIPTION: This is the main entry point for the Address Book
* application.
*
* PARAMETERS: nothing
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 6/5/95 Initial Revision
* jmp 10/01/99 Changed call to DmOpenDatabaseByTypeCreator() to
* AddrGetDatabase().
* jmp 10/02/99 Made the support for the sysAppLaunchCmdExgReceiveData
* sysAppLaunchCmdExgAskUser launch codes more like their
* counterparts in Datebook, Memo, and ToDo.
* jmp 10/13/99 Fix bug #22832: Call AddrGetDatabase() on look-up
* sublaunch to create default database if it doesn't
* exists (at least the user can now see that nothing
* exists rather than just having nothing happen).
* jmp 10/14/99 Oops... wasn't closing the database when we opened it
* in the previous change! Fixes bug #22944.
* jmp 10/16/99 Just create a database on hard reset if the default
* database doesn't exist.
* jmp 11/04/99 Eliminate extraneous FrmSaveAllForms() call from sysAppLaunchCmdExgAskUser
* since it was already being done in sysAppLaunchCmdExgReceiveData if
* the user affirmed sysAppLaunchCmdExgAskUser.
*
***********************************************************************/
// Note: We need to create a branch island to PilotMain in order to successfully
// link this application for the device.
UInt32 PrvAppPilotMain (UInt16 cmd, MemPtr cmdPBP, UInt16 launchFlags)
{
Err error = errNone;
DmOpenRef dbP;
switch (cmd)
{
// The only place the following define is used is in the Jamfile for this application.
// It's sole purpose is to provide a way to check if cross segment calls are being made
// when application globals are unavailable.
#ifndef SINGLE_SEGMENT_CHECK
case sysAppLaunchCmdNormalLaunch:
error = PrvAppStart ();
if (error)
return (error);
FrmGotoForm (ListView);
PrvAppEventLoop ();
PrvAppStop ();
break;
#endif
case sysAppLaunchCmdFind:
PrvAppSearch ((FindParamsPtr) cmdPBP);
break;
// This action code could be sent to the app when it's already running.
case sysAppLaunchCmdGoTo:
{
Boolean launched;
launched = launchFlags & sysAppLaunchFlagNewGlobals;
#ifndef SINGLE_SEGMENT_CHECK
if (launched)
{
error = PrvAppStart ();
if (error)
return (error);
}
#endif
PrvAppGoToItem ((GoToParamsPtr)cmdPBP, launched);
#ifndef SINGLE_SEGMENT_CHECK
if (launched)
{
PrvAppEventLoop ();
PrvAppStop ();
}
}
#endif
break;
case sysAppLaunchCmdSyncNotify:
PrvAppHandleSync();
break;
// Launch code sent to running app before sysAppLaunchCmdFind
// or other action codes that will cause data PrvAppSearches or manipulation.
case sysAppLaunchCmdSaveData:
FrmSaveAllForms ();
break;
// We are requested to initialize an empty database (by sync app).
case sysAppLaunchCmdInitDatabase:
PrvAppLaunchCmdDatabaseInit (((SysAppLaunchCmdInitDatabaseType*)cmdPBP)->dbP);
break;
// 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.
case sysAppLaunchCmdSystemReset:
if (((SysAppLaunchCmdSystemResetType*)cmdPBP)->createDefaultDB)
{
error = ToolsCreateDefaultDatabase();
// Register to receive vcf files on hard reset.
TransferRegisterData();
}
ToolsRegisterLocaleChangingNotification();
break;
// Present the user with ui to perform a lookup and return a string
// with information from the selected record.
case sysAppLaunchCmdLookup:
Lookup((AddrLookupParamsPtr) cmdPBP);
break;
case 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))
{
AddrDBGetDatabase (&dbP, dmModeReadWrite);
}
else
dbP = AddrDB;
if (dbP != NULL)
{
ToolsCustomAcceptBeamDialog (dbP, (ExgAskParamPtr) cmdPBP);
if (!(launchFlags & sysAppLaunchFlagSubCall))
DmCloseDatabase(dbP);
}
break;
case sysAppLaunchCmdExgReceiveData:
{
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 = AddrDBGetDatabase (&dbP, dmModeReadWrite);
}
else
{
dbP = AddrDB;
// We don't save the current record because the keyboard dialog could have
// stolen the table's field's handle. There's no need anyway.
// TransferReceiveData() inserts the received record in sorted order. This may change the
// index of the current record. So we remember its UID here, and refresh our copy of its
// index afterwards.
if (CurrentRecord != noRecord)
DmRecordInfo(dbP, CurrentRecord, NULL, ¤tUID, NULL);
}
if (dbP != NULL)
{
error = TransferReceiveData(dbP, (ExgSocketPtr) cmdPBP);
if (launchFlags & sysAppLaunchFlagSubCall)
{
if (CurrentRecord != noRecord)
{
if (DmFindRecordByID(dbP, currentUID, &CurrentRecord) != 0)
CurrentRecord = noRecord; // 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
}
break;
case sysAppLaunchCmdExgPreview:
TransferPreview((ExgPreviewInfoType *)cmdPBP);
break;
case sysAppLaunchCmdNotify :
{
if (((SysNotifyParamType*)cmdPBP)->notifyType == sysNotifyLocaleChangedEvent)
{
DmSearchStateType PrvAppSearchState;
LocalID dbID;
UInt16 cardNo;
// Since the locale has changed, delete the existing database
// and re-create it for the new locale
error = DmGetNextDatabaseByTypeCreator (true, &PrvAppSearchState, addrDBType,
sysFileCAddress, true, &cardNo, &dbID);
if (!error)
DmDeleteDatabase(cardNo, dbID);
error = ToolsCreateDefaultDatabase();
}
}
break;
}
return error;
}
/***********************************************************************
*
* FUNCTION: PrvAppStart
*
* DESCRIPTION: This routine opens the application's resource file and
* database.
*
* PARAMETERS: nothing
*
* RETURNED: Err - standard error code
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 6/5/95 Initial Revision
* vmk 12/12/97 Get amplitude for scroll sound
* BGT 1/8/98 Use AddressLoadPrefs to load and fix up the
* application preferences
* grant 4/6/99 Moved code to set backup bit into SetDBAttrBits.
* jmp 10/1/99 Call new AddrGetDataBase() to create database
* if it doesn't already exist.
*
***********************************************************************/
Err PrvAppStart(void)
{
Err err = 0;
UInt16 mode;
AddrAppInfoPtr appInfoPtr;
// Determime if secret records should be shown.
PrivateRecordVisualStatus = (privateRecordViewEnum)PrefGetPreference(prefShowPrivateRecords);
mode = (PrivateRecordVisualStatus == hidePrivateRecords) ?
dmModeReadWrite : (dmModeReadWrite | dmModeShowSecret);
// Find the application's data file. If it doesn't exist create it.
err = AddrDBGetDatabase(&AddrDB, mode);
if (err)
return err;
appInfoPtr = (AddrAppInfoPtr) AddrDBAppInfoGetPtr(AddrDB);
ErrFatalDisplayIf(appInfoPtr == NULL, "Missing app info block");
// Update the database to look and behave properly for the given country.
if (appInfoPtr->country != PrefGetPreference(prefCountry))
AddrDBChangeCountry(appInfoPtr);
ToolsInitPhoneLabelLetters(appInfoPtr, PhoneLabelLetters);
SortByCompany = appInfoPtr->misc.sortByCompany;
// Load the application preferences and fix them up if need be. (BGT)
PrefsLoad(appInfoPtr); // (BGT)
// Initialize the default auto-fill databases
AutoFillInitDB(titleDBType, sysFileCAddress, titleDBName, titleAFInitStr);
AutoFillInitDB(companyDBType, sysFileCAddress, companyDBName, companyAFInitStr);
AutoFillInitDB(cityDBType, sysFileCAddress, cityDBName, cityAFInitStr);
AutoFillInitDB(stateDBType, sysFileCAddress, stateDBName, stateAFInitStr);
AutoFillInitDB(countryDBType, sysFileCAddress, countryDBName, countryAFInitStr);
// Start watching the button pressed to get into this app. If it's held down
// long enough then we need to send the business card.
TickAppButtonPushed = TimGetTicks();
// Mask off the key to avoid repeat keys causing clicking sounds
KeySetMask(~KeyCurrentState());
return (err);
}
/***********************************************************************
*
* FUNCTION: PrvAppStop
*
* DESCRIPTION: This routine close the application's database
* and save the current state of the application.
*
* PARAMETERS: nothing
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* art 6/5/95 Initial Revision
*
***********************************************************************/
void PrvAppStop(void)
{
// Write the preferences / saved-state information.
PrefsSave();
// Send a frmSave event to all the open forms.
FrmSaveAllForms ();
// Close all the open forms.
FrmCloseAllForms ();
// Close the application's data file.
DmCloseDatabase (AddrDB);
}
/***********************************************************************
*
* FUNCTION: PrvAppEventLoop
*
* DESCRIPTION: This routine is the event loop for the Address Book
* aplication.
*
* PARAMETERS: nothing
*
* RETURNED: nothing
*
* REVISION HISTORY:
* Name Date Description
* ---- ---- -----------
* roger 6/5/95 Initial Revision
*
***********************************************************************/
void PrvAppEventLoop (void)
{
UInt16 error;
EventType event;
do
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -