This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
magicka/deps/cdk-5.0-20161210/demos/rolodex.c
2017-03-20 21:40:32 +10:00

1938 lines
53 KiB
C

/* $Id: rolodex.c,v 1.29 2016/12/04 15:22:16 tom Exp $ */
#include "rolodex.h"
#ifdef HAVE_XCURSES
char *XCursesProgramName = "rolodex";
#endif
#define MYSIZE 256
static void fmt1s (char *target, const char *format, const char *source)
{
int limit = MYSIZE - (int)(strlen (format) + strlen (source));
if (limit > 0)
sprintf (target, format, limit, source);
else
*target = '\0';
}
/*
* This is the main part of the loop.
*/
int main (void)
{
/* Declare variables. */
CDKSCREEN *cdkscreen;
CDKMENU *rolodexMenu;
CDKLABEL *rolodexTitle;
SRolodex groupList[MAXGROUPS];
const char *menulist[MAX_MENU_ITEMS][MAX_SUB_ITEMS];
const char *title[5];
char *home, temp[MYSIZE];
const char *mesg[15];
int subMenuSize[10], menuLocations[10];
int group, ret, x;
int groupCount = 0;
cdkscreen = initCDKScreen (NULL);
/* Start CDK color. */
initCDKColor ();
/* Create the menu lists. */
menulist[0][0] = "</U>File";
menulist[0][1] = "</B/5>Open ";
menulist[0][2] = "</B/5>Save ";
menulist[0][3] = "</B/5>Save As";
menulist[0][4] = "</B/5>Quit ";
menulist[1][0] = "</U>Groups";
menulist[1][1] = "</B/5>New ";
menulist[1][2] = "</B/5>Open ";
menulist[1][3] = "</B/5>Delete";
menulist[2][0] = "</U>Print";
menulist[2][1] = "</B/5>Print Groups";
menulist[3][0] = "</U>Help";
menulist[3][1] = "</B/5>About Rolodex ";
menulist[3][2] = "</B/5>Rolodex Statistics";
/* Set up the sub-menu sizes and their locations. */
subMenuSize[0] = 5;
menuLocations[0] = LEFT;
subMenuSize[1] = 4;
menuLocations[1] = LEFT;
subMenuSize[2] = 2;
menuLocations[2] = LEFT;
subMenuSize[3] = 3;
menuLocations[3] = RIGHT;
/* Create the menu. */
rolodexMenu = newCDKMenu (cdkscreen, menulist, 4,
subMenuSize, menuLocations,
TOP, A_BOLD | A_UNDERLINE, A_REVERSE);
/* Create the title. */
title[0] = "<C></U>Cdk Rolodex";
title[1] = "<C></B/24>Written by Mike Glover";
rolodexTitle = newCDKLabel (cdkscreen, CENTER, CENTER,
(CDK_CSTRING2)title, 2,
FALSE, FALSE);
/* Define the help key binding. */
bindCDKObject (vMENU, rolodexMenu, '?', helpCB, 0);
/* Draw the CDK screen. */
refreshCDKScreen (cdkscreen);
/* Check the value of the HOME env var. */
home = getenv ("HOME");
if (home != 0)
{
/* Make sure the $HOME/.rolodex directory exists. */
fmt1s (temp, "%.*s/.rolodex", home);
/* Set the value of the global rolodex DBM directory. */
GDBMDir = copyChar (temp);
/* Set the value of the global RC filename. */
fmt1s (temp, "%.*s/.rolorc", home);
GRCFile = copyChar (temp);
}
else
{
/* Set the value of the global rolodex DBM directory. */
GDBMDir = copyChar (".rolodex");
/* Set the value of the global RC filename. */
GRCFile = copyChar (".rolorc");
}
/* Make the rolodex directory. */
#if defined (__MINGW32__)
mkdir (GDBMDir);
#else
mkdir (GDBMDir, 0755);
#endif
/* Open the rolodex RC file. */
groupCount = readRCFile (GRCFile, groupList);
/* Check the value of groupCount. */
if (groupCount < 0)
{
/* The RC file seems to be corrupt. */
fmt1s (temp, "<C></B/16>The RC file (%.*s) seems to be corrupt.", GRCFile);
mesg[0] = temp;
mesg[1] = "<C></B/16>No rolodex groups were loaded.";
mesg[2] = "<C>Press any key to continue.";
popupLabel (cdkscreen, (CDK_CSTRING2)mesg, 3);
groupCount = 0;
}
else if (groupCount == 0)
{
mesg[0] = "<C></B/24>Empty rolodex RC file. No groups loaded.";
mesg[1] = "<C>Press any key to continue.";
popupLabel (cdkscreen, (CDK_CSTRING2)mesg, 2);
}
else
{
if (groupCount == 1)
{
sprintf (temp, "<C></24>There was 1 group loaded from the RC file.");
}
else
{
sprintf (temp,
"<C></24>There were %d groups loaded from the RC file.", groupCount);
}
mesg[0] = temp;
mesg[1] = "<C>Press any key to continue.";
popupLabel (cdkscreen, (CDK_CSTRING2)mesg, 2);
}
/* Loop until we are done. */
for (;;)
{
/* Activate the menu */
int selection = activateCDKMenu (rolodexMenu, 0);
/* Check the return value of the selection. */
if (selection == 0)
{
/* Open the rolodex RC file. */
groupCount = openNewRCFile (cdkscreen, groupList, groupCount);
}
else if (selection == 1)
{
/* Write out the RC file. */
ret = writeRCFile (cdkscreen, GRCFile, groupList, groupCount);
/* Reset the saved flag if the rc file saved ok. */
if (ret != 0)
{
GGroupModified = 0;
}
}
else if (selection == 2)
{
/* Save as. */
ret = writeRCFileAs (cdkscreen, groupList, groupCount);
/* Reset the saved flag if the rc file saved ok. */
if (ret != 0)
{
GGroupModified = 0;
}
}
else if (selection == 3)
{
/* Has anything changed??? */
if (GGroupModified != 0)
{
/* Write out the RC file. */
writeRCFile (cdkscreen, GRCFile, groupList, groupCount);
}
/* Remove the CDK widget pointers. */
destroyCDKMenu (rolodexMenu);
destroyCDKLabel (rolodexTitle);
destroyCDKScreen (cdkscreen);
/* Free up other pointers. */
freeChar (GCurrentGroup);
freeChar (GRCFile);
freeChar (GDBMDir);
/* Clean up the group information. */
for (x = 0; x < groupCount; x++)
{
freeChar (groupList[x].name);
freeChar (groupList[x].desc);
freeChar (groupList[x].dbm);
}
/* Shutdown CDK. */
endCDK ();
/* Exit cleanly. */
ExitProgram (EXIT_SUCCESS);
}
else if (selection == 100)
{
/* Add a new group to the list. */
groupCount = addRolodexGroup (cdkscreen, groupList, groupCount);
}
else if (selection == 101)
{
/* If there are no groups, ask them if they want to create a new one. */
if (groupCount == 0)
{
const char *buttons[] =
{
"<Yes>",
"<No>"
};
mesg[0] = "<C>There are no groups defined.";
mesg[1] = "<C>Do you want to define a new group?";
/* Add the group if they said yes. */
if (popupDialog (cdkscreen,
(CDK_CSTRING2)mesg, 2,
(CDK_CSTRING2)buttons, 2) == 0)
{
groupCount = addRolodexGroup (cdkscreen, groupList, groupCount);
}
}
else
{
/* Get the number of the group to open. */
group = pickRolodexGroup (cdkscreen,
"<C></B/29>Open Rolodex Group",
groupList, groupCount);
/* Make sure a group was picked. */
if (group >= 0)
{
/* Set the global variable GCurrentGroup */
freeChar (GCurrentGroup);
GCurrentGroup = copyChar (groupList[group].name);
/* Try to open the DBM file and read the contents. */
useRolodexGroup (cdkscreen,
groupList[group].name,
groupList[group].desc,
groupList[group].dbm);
}
}
}
else if (selection == 102)
{
/* Delete the group chosen. */
groupCount = deleteRolodexGroup (cdkscreen, groupList, groupCount);
}
else if (selection == 200)
{
/* Print Phone Number Group. */
printGroupNumbers (cdkscreen, groupList, groupCount);
}
else if (selection == 300)
{
/* About Rolodex. */
aboutCdkRolodex (cdkscreen);
}
else if (selection == 301)
{
displayRolodexStats (ScreenOf (rolodexMenu), groupCount);
}
}
}
/*
* This writes out the new RC file.
*/
int writeRCFile (CDKSCREEN *screen, char *filename, SRolodex * groupList, int groupCount)
{
char *mesg[5];
char temp[MYSIZE];
time_t clck;
FILE *fd;
int x;
/* Can we open the file? */
if ((fd = fopen (filename, "w")) == 0)
{
fmt1s (temp, "</B/16>The file <%.*s> could not be opened.", filename);
mesg[0] = copyChar (temp);
#ifdef HAVE_STRERROR
fmt1s (temp, "<C></B/16>%.*s", strerror (errno));
#else
sprintf (temp, "<C></B/16>Unknown reason.");
#endif
mesg[1] = copyChar (temp);
mesg[2] = copyChar ("<C>Press any key to continue.");
popupLabel (screen, (CDK_CSTRING2)mesg, 3);
freeCharList (mesg, 3);
return (0);
}
/* Get the current time. */
time (&clck);
/* Put some comments at the top of the header. */
fprintf (fd, "#\n");
fprintf (fd, "# This file was automatically generated on %s", ctime (&clck));
fprintf (fd, "#\n");
/* Start writing the RC file. */
for (x = 0; x < groupCount; x++)
{
fprintf (fd, "%s%c%s%c%s\n",
groupList[x].name, CTRL ('V'),
groupList[x].desc, CTRL ('V'),
groupList[x].dbm);
}
fclose (fd);
/* Pop up a message stating that it has been saved. */
if (groupCount == 1)
{
sprintf (temp, "There was 1 group saved to file");
mesg[0] = copyChar (temp);
}
else
{
sprintf (temp, "There were %d groups saved to file", groupCount);
mesg[0] = copyChar (temp);
}
fmt1s (temp, "<C>%.*s", filename);
mesg[1] = copyChar (temp);
mesg[2] = copyChar ("<C>Press any key to continue.");
popupLabel (screen, (CDK_CSTRING2)mesg, 3);
freeCharList (mesg, 3);
return (1);
}
/*
* This allows the user to pick a DBM file to open.
*/
int pickRolodexGroup (CDKSCREEN *screen,
const char *title,
SRolodex * groupList,
int groupCount)
{
/* *INDENT-EQLS* */
CDKSCROLL *roloList = 0;
int height = groupCount;
char *mesg[MAXGROUPS];
char temp[MYSIZE];
int selection, x;
/* Determine the height of the scrolling list. */
if (groupCount > 5)
{
height = 5;
}
height += 3;
/* Copy the names of the scrolling list into an array. */
for (x = 0; x < groupCount; x++)
{
fmt1s (temp, "<C></B/29>%.*s", groupList[x].name);
mesg[x] = copyChar (temp);
}
/* Create the scrolling list. */
roloList = newCDKScroll (screen, CENTER, CENTER, NONE,
height, 50, title,
(CDK_CSTRING2)mesg, groupCount,
NONUMBERS, A_REVERSE, TRUE, FALSE);
/* Create a callback to the scrolling list. */
bindCDKObject (vSCROLL, roloList, '?', groupInfoCB, groupList);
/* Activate the scrolling list. */
selection = activateCDKScroll (roloList, 0);
/* Destroy the scrolling list. */
destroyCDKScroll (roloList);
freeCharList (mesg, (unsigned)groupCount);
/* Return the item selected. */
return selection;
}
/*
* This allows the user to add a rolo group to the list.
*/
int addRolodexGroup (CDKSCREEN *screen, SRolodex * groupList, int groupCount)
{
/* *INDENT-EQLS* */
CDKENTRY *newName = 0;
CDKENTRY *newDesc = 0;
const char *mesg[4];
char *desc;
char *newGroupName;
char temp[MYSIZE];
int x;
/* Create the name widget. */
newName = newCDKEntry (screen, CENTER, 8,
"<C></B/29>New Group Name",
"</B/29> Name: ",
A_NORMAL, '_', vMIXED,
20, 2, MYSIZE, TRUE, FALSE);
/* Get the name. */
newGroupName = activateCDKEntry (newName, 0);
/* Make sure they didn't hit escape. */
if (newName->exitType == vESCAPE_HIT)
{
mesg[0] = "<C></B/16>Add Group Canceled.";
destroyCDKEntry (newName);
popupLabel (screen, (CDK_CSTRING2)mesg, 1);
return groupCount;
}
/* Make sure that group name does not already exist. */
for (x = 0; x < groupCount; x++)
{
if (strcmp (newGroupName, groupList[x].name) == 0)
{
fmt1s (temp, "<C></B/16>Sorry the group (%.*s) already exists.", newGroupName);
mesg[0] = temp;
popupLabel (screen, (CDK_CSTRING2)mesg, 1);
destroyCDKEntry (newName);
return groupCount;
}
}
/* Keep the name. */
groupList[groupCount].name = copyChar (newGroupName);
/* Create the description widget. */
newDesc = newCDKEntry (screen, CENTER, 13,
"<C></B/29>Group Description",
"</B/29>Descriprion: ",
A_NORMAL, '_', vMIXED,
20, 2, MYSIZE, TRUE, FALSE);
/* Get the description. */
desc = activateCDKEntry (newDesc, 0);
/* Check if they hit escape or not. */
if (newDesc->exitType == vESCAPE_HIT)
{
groupList[groupCount].desc = copyChar ("No Description Provided.");
}
else
{
groupList[groupCount].desc = copyChar (desc);
}
/* Create the DBM filename. */
sprintf (temp, "%s/%s.phl", GDBMDir, groupList[groupCount].name);
groupList[groupCount].dbm = copyChar (temp);
/* Inrement the group count. */
groupCount++;
GGroupModified = 1;
/* Destroy the widgets. */
destroyCDKEntry (newName);
destroyCDKEntry (newDesc);
return groupCount;
}
/*
* This displays rolodex information.
*/
void displayRolodexStats (CDKSCREEN *screen, int groupCount)
{
/* Declare local variables. */
char *mesg[6], temp[MYSIZE];
/* Create the information to display. */
sprintf (temp, "<C></U>Rolodex Statistics");
mesg[0] = copyChar (temp);
fmt1s (temp, "</B/5>Read Command Filename<!B!5> </U>%.*s<!U>", GRCFile);
mesg[1] = copyChar (temp);
sprintf (temp, "</B/5>Group Count <!B!5> </U>%d<!U>", groupCount);
mesg[2] = copyChar (temp);
/* Display the message. */
popupLabel (screen, (CDK_CSTRING2)mesg, 3);
freeCharList (mesg, 3);
}
/*
* This function gets a new rc filename and saves the contents of the
* groups under that name.
*/
int writeRCFileAs (CDKSCREEN *screen, SRolodex * groupList, int groupCount)
{
/* Declare local variables. */
CDKENTRY *newRCFile;
char *newFilename;
int ret;
/* Create the entry field. */
newRCFile = newCDKEntry (screen, CENTER, CENTER,
"<C></R>Save As",
"Filename: ",
A_NORMAL, '_', vMIXED,
20, 2, MYSIZE, TRUE, FALSE);
/* Add a pre-process function so no spaces are introduced. */
setCDKEntryPreProcess (newRCFile, entryPreProcessCB, 0);
/* Get the filename. */
newFilename = activateCDKEntry (newRCFile, 0);
/* Check if they hit escape or not. */
if (newRCFile->exitType == vESCAPE_HIT)
{
destroyCDKEntry (newRCFile);
return 1;
}
/* Call the function to save the RC file. */
ret = writeRCFile (screen, newFilename, groupList, groupCount);
/* Reset the saved flag if the rc file saved ok. */
if (ret != 0)
{
/* Change the default filename. */
freeChar (GRCFile);
GRCFile = copyChar (newFilename);
GGroupModified = 0;
}
/* Clean up. */
destroyCDKEntry (newRCFile);
return 1;
}
/*
* This opens a new RC file.
*/
int openNewRCFile (CDKSCREEN *screen, SRolodex * groupList, int groupCount)
{
/* Declare local variables. */
CDKFSELECT *fileSelector;
char *filename, *mesg[10];
int x;
/* Get the filename. */
fileSelector = newCDKFselect (screen, CENTER, CENTER, 20, 55,
"<C>Open RC File",
"Filename: ",
A_NORMAL, '.', A_REVERSE,
"</5>", "</48>", "</N>", "</N>",
TRUE, FALSE);
/* Activate the file selector. */
filename = activateCDKFselect (fileSelector, 0);
/* Check if the file selector left early. */
if (fileSelector->exitType == vESCAPE_HIT)
{
destroyCDKFselect (fileSelector);
mesg[0] = copyChar ("Open New RC File Aborted.");
popupLabel (screen, (CDK_CSTRING2)mesg, 1);
freeCharList (mesg, 1);
return groupCount;
}
/* Clean out the old information. */
for (x = 0; x < groupCount; x++)
{
freeChar (groupList[x].name);
freeChar (groupList[x].desc);
freeChar (groupList[x].dbm);
}
/* Open the RC file. */
groupCount = readRCFile (filename, groupList);
/* Check the return value. */
if (groupCount < 0)
{
char temp[MYSIZE];
/* This file does not appear to be a rolodex file. */
mesg[0] = copyChar ("<C></B/16>The file<!B!16>");
fmt1s (temp, "<C></B/16>(%.*s)<!B!16>", filename);
mesg[1] = copyChar (temp);
mesg[2] = copyChar ("<C>does not seem to be a rolodex RC file.");
mesg[3] = copyChar ("<C>Press any key to continue.");
popupLabel (screen, (CDK_CSTRING2)mesg, 4);
freeCharList (mesg, 4);
groupCount = 0;
}
/* Clean up. */
destroyCDKFselect (fileSelector);
return groupCount;
}
/*
* This reads the users rc file.
*/
int readRCFile (char *filename, SRolodex * groupList)
{
/* *INDENT-EQLS* */
int groupsFound = 0;
int errorsFound = 0;
char **lines = 0;
char **items;
int linesRead, chunks, x;
/* Open the file and start reading. */
linesRead = CDKreadFile (filename, &lines);
/* Check the number of lines read. */
if (linesRead == 0)
{
return (0);
}
/*
* Cycle through what was given to us and save it.
*/
for (x = 0; x < linesRead; x++)
{
/* Strip white space from the line. */
stripWhiteSpace (vBOTH, lines[x]);
/* Only split lines which do not start with a # */
if (strlen (lines[x]) != 0 && lines[x][0] != '#')
{
items = CDKsplitString (lines[x], CTRL ('V'));
chunks = (int)CDKcountStrings ((CDK_CSTRING2)items);
/* Only take the ones which fit the format. */
if (chunks == 3)
{
/* Clean off the name and DB name. */
stripWhiteSpace (vBOTH, items[0]);
stripWhiteSpace (vBOTH, items[1]);
stripWhiteSpace (vBOTH, items[2]);
/* Set the group name and DB name. */
groupList[groupsFound].name = items[0];
groupList[groupsFound].desc = items[1];
groupList[groupsFound].dbm = items[2];
groupsFound++;
free (items);
}
else
{
CDKfreeStrings (items);
errorsFound++;
}
}
}
/* Clean up. */
CDKfreeStrings (lines);
/* Check the number of groups to the number of errors. */
if (errorsFound > 0 && groupsFound == 0)
{
/* This does NOT look like the rolodex RC file. */
return -1;
}
return groupsFound;
}
/*
* This function allows the user to add/delete/modify/save the
* contents of a rolodex group.
*/
void useRolodexGroup (CDKSCREEN *screen, char *groupName, char *groupDesc
GCC_UNUSED, char *groupDBM)
{
/* *INDENT-EQLS* */
CDKSCROLL *nameList = 0;
CDKLABEL *helpWindow = 0;
SPhoneData phoneData;
char *Index[MAX_ITEMS];
const char *title[3];
const char *mesg[3];
char temp[MYSIZE];
int phoneCount, selection, height, x;
/* Set up the help window at the bottom of the screen. */
/* *INDENT-EQLS* */
title[0] = "<C><#HL(30)>";
title[1] = "<C>Press </B>?<!B> to get detailed help.";
title[2] = "<C><#HL(30)>";
helpWindow = newCDKLabel (screen, CENTER, BOTTOM,
(CDK_CSTRING2)title, 3,
FALSE, FALSE);
drawCDKLabel (helpWindow, FALSE);
/* Open the DBM file and read in the contents of the file */
phoneCount = readPhoneDataFile (groupDBM, &phoneData);
phoneData.recordCount = phoneCount;
/* Check the number of entries returned. */
if (phoneCount == 0)
{
/*
* They tried to open an empty group, maybe they want to
* add a new entry to this number.
*/
const char *buttons[] =
{
"<Yes>",
"<No>"
};
mesg[0] = "<C>There were no entries in this group.";
mesg[1] = "<C>Do you want to add a new listng?";
if (popupDialog (screen,
(CDK_CSTRING2)mesg, 2,
(CDK_CSTRING2)buttons, 2) == 1)
{
destroyCDKLabel (helpWindow);
return;
}
/* Get the information for a new number. */
if (addPhoneRecord (screen, &phoneData) != 0)
{
return;
}
}
else if (phoneCount < 0)
{
mesg[0] = "<C>Could not open the database for this group.";
popupLabel (screen, (CDK_CSTRING2)mesg, 1);
destroyCDKLabel (helpWindow);
return;
}
/* Set up the data needed for the scrolling list. */
for (x = 0; x < phoneData.recordCount; x++)
{
SPhoneRecord *phoneRecord = &phoneData.record[x];
sprintf (temp, "</B/29>%s (%s)", phoneRecord->name, GLineType[phoneRecord->lineType]);
Index[x] = copyChar (temp);
}
fmt1s (temp, "<C>Listing of Group </U>%.*s", groupName);
height = (phoneData.recordCount > 5 ? 8 : phoneData.recordCount + 3);
/* Create the scrolling list. */
nameList = newCDKScroll (screen, CENTER, CENTER, RIGHT,
height, 50, temp,
(CDK_CSTRING2)Index,
phoneData.recordCount,
NUMBERS, A_REVERSE, TRUE, FALSE);
/* Clean up. */
for (x = 0; x < phoneData.recordCount; x++)
{
freeChar (Index[x]);
}
/* Create key bindings. */
bindCDKObject (vSCROLL, nameList, 'i', insertPhoneEntryCB, &phoneData);
bindCDKObject (vSCROLL, nameList, 'd', deletePhoneEntryCB, &phoneData);
bindCDKObject (vSCROLL, nameList, KEY_DC, deletePhoneEntryCB, &phoneData);
bindCDKObject (vSCROLL, nameList, '?', phoneEntryHelpCB, 0);
/* Let them play. */
selection = 0;
while (selection >= 0)
{
/* Get the information they want to view. */
selection = activateCDKScroll (nameList, 0);
/* Display the information. */
if (selection >= 0)
{
/* Display the information. */
displayPhoneInfo (screen, phoneData.record[selection]);
}
}
/* Save the rolodex information to file. */
if (savePhoneDataFile (groupDBM, &phoneData) == 0)
{
/* Something happened. */
mesg[0] = "<C>Could not save phone data to data file.";
mesg[1] = "<C>All changes have been lost.";
popupLabel (screen, (CDK_CSTRING2)mesg, 2);
}
/* Clean up. */
for (x = 0; x < phoneData.recordCount; x++)
{
freeChar (phoneData.record[x].name);
freeChar (phoneData.record[x].phoneNumber);
freeChar (phoneData.record[x].address);
freeChar (phoneData.record[x].city);
freeChar (phoneData.record[x].province);
freeChar (phoneData.record[x].postalCode);
freeChar (phoneData.record[x].desc);
}
destroyCDKScroll (nameList);
destroyCDKLabel (helpWindow);
}
/*
* This opens a phone data file and returns the number of elements read.
*/
int readPhoneDataFile (char *dataFile, SPhoneData * phoneData)
{
/* *INDENT-EQLS* */
char **lines = 0;
char **items;
int linesRead = 0;
int chunks = 0;
int linesFound = 0;
int x;
/* Open the file and start reading. */
linesRead = CDKreadFile (dataFile, &lines);
/* Check the number of lines read. */
if (linesRead <= 0)
{
return (0);
}
/*
* Cycle through what was given to us and save it.
*/
for (x = 0; x < linesRead; x++)
{
if (lines[x][0] != '#')
{
/* Split the string. */
items = CDKsplitString (lines[x], CTRL ('V'));
chunks = (int)CDKcountStrings ((CDK_CSTRING2)items);
/* Copy the chunks. */
if (chunks == 8)
{
int myType = atoi (items[1]);
/* *INDENT-EQLS* */
phoneData->record[linesFound].name = items[0];
phoneData->record[linesFound].lineType = (ELineType) myType;
phoneData->record[linesFound].phoneNumber = items[2];
phoneData->record[linesFound].address = items[3];
phoneData->record[linesFound].city = items[4];
phoneData->record[linesFound].province = items[5];
phoneData->record[linesFound].postalCode = items[6];
phoneData->record[linesFound].desc = items[7];
freeChar (items[1]);
free (items);
linesFound++;
}
else
{
/* Bad line in the file; recover the memory. */
CDKfreeStrings (items);
}
}
}
/* Clean up. */
CDKfreeStrings (lines);
/* Keep the record count and return. */
phoneData->recordCount = linesFound;
return linesFound;
}
/*
* This opens a phone data file and returns the number of elements read.
*/
int savePhoneDataFile (char *filename, SPhoneData * phoneData)
{
time_t clck;
FILE *fd;
int x;
/* Can we open the file? */
if ((fd = fopen (filename, "w")) == 0)
{
return 0;
}
/* Get the current time. */
time (&clck);
/* Add the header to the file. */
fprintf (fd, "#\n");
fprintf (fd, "# This file was automatically saved on %s", ctime (&clck));
fprintf (fd, "# There should be %d phone numbers in this file.\n", phoneData->recordCount);
fprintf (fd, "#\n");
/* Cycle through the data and start writing it to the file. */
for (x = 0; x < phoneData->recordCount; x++)
{
SPhoneRecord *phoneRecord = &phoneData->record[x];
/* Check the phone type. */
if (phoneRecord->lineType == vCell || phoneRecord->lineType == vPager)
{
fprintf (fd, "%s%c%d%c%s%c-%c-%c-%c-%c%s\n",
phoneRecord->name, CTRL ('V'),
phoneRecord->lineType, CTRL ('V'),
phoneRecord->phoneNumber, CTRL ('V'),
CTRL ('V'), CTRL ('V'), CTRL ('V'), CTRL ('V'),
phoneRecord->desc);
}
else
{
fprintf (fd, "%s%c%d%c%s%c%s%c%s%c%s%c%s%c%s\n",
phoneRecord->name, CTRL ('V'),
phoneRecord->lineType, CTRL ('V'),
phoneRecord->phoneNumber, CTRL ('V'),
phoneRecord->address, CTRL ('V'),
phoneRecord->city, CTRL ('V'),
phoneRecord->province, CTRL ('V'),
phoneRecord->postalCode, CTRL ('V'),
phoneRecord->desc);
}
}
fclose (fd);
return 1;
}
/*
* This displays the information about the phone record.
*/
void displayPhoneInfo (CDKSCREEN *screen, SPhoneRecord record)
{
/* Declare local variables. */
char *mesg[10], temp[MYSIZE];
/* Check the type of line it is. */
if (record.lineType == vVoice ||
record.lineType == vData1 ||
record.lineType == vData2 ||
record.lineType == vData3 ||
record.lineType == vFAX1 ||
record.lineType == vFAX2 ||
record.lineType == vFAX3)
{
/* Create the information to display. */
fmt1s (temp, "<C></U>%.*s Phone Record", GLineType[record.lineType]);
mesg[0] = copyChar (temp);
fmt1s (temp, "</B/29>Name <!B!29>%.*s", record.name);
mesg[1] = copyChar (temp);
fmt1s (temp, "</B/29>Phone Number<!B!29>%.*s", record.phoneNumber);
mesg[2] = copyChar (temp);
fmt1s (temp, "</B/29>Address <!B!29>%.*s", record.address);
mesg[3] = copyChar (temp);
fmt1s (temp, "</B/29>City <!B!29>%.*s", record.city);
mesg[4] = copyChar (temp);
fmt1s (temp, "</B/29>Province <!B!29>%.*s", record.province);
mesg[5] = copyChar (temp);
fmt1s (temp, "</B/29>Postal Code <!B!29>%.*s", record.postalCode);
mesg[6] = copyChar (temp);
fmt1s (temp, "</B/29>Comment <!B!29>%.*s", record.desc);
mesg[7] = copyChar (temp);
/* Pop the information up on the screen. */
popupLabel (screen, (CDK_CSTRING2)mesg, 8);
/* Clean up. */
freeChar (mesg[0]);
freeChar (mesg[1]);
freeChar (mesg[2]);
freeChar (mesg[3]);
freeChar (mesg[4]);
freeChar (mesg[5]);
freeChar (mesg[6]);
freeChar (mesg[7]);
}
else if (record.lineType == vPager || record.lineType == vCell)
{
/* Create the information to display. */
fmt1s (temp, "<C></U>%.*s Phone Record", GLineType[record.lineType]);
mesg[0] = copyChar (temp);
fmt1s (temp, "</B/29>Name <!B!29>%.*s", record.name);
mesg[1] = copyChar (temp);
fmt1s (temp, "</B/29>Phone Number<!B!29>%.*s", record.phoneNumber);
mesg[2] = copyChar (temp);
fmt1s (temp, "</B/29>Comment <!B!29>%.*s", record.desc);
mesg[3] = copyChar (temp);
/* Pop the information up on the screen. */
popupLabel (screen, (CDK_CSTRING2)mesg, 4);
freeCharList (mesg, 4);
}
else
{
mesg[0] = copyChar ("<C></R>Error<!R> </U>Unknown Phone Line Type");
mesg[1] = copyChar ("<C>Can not display information.");
popupLabel (screen, (CDK_CSTRING2)mesg, 2);
freeCharList (mesg, 2);
}
}
/*
* This function displays a little pop up window discussing this demo.
*/
void aboutCdkRolodex (CDKSCREEN *screen)
{
const char *mesg[15];
mesg[0] = "<C></U>About Cdk Rolodex";
mesg[1] = " ";
mesg[2] = "</B/24>This demo was written to demonstrate the widgets";
mesg[3] = "</B/24>available with the Cdk library. Not all of the";
mesg[4] = "</B/24>Cdk widgets are used, but most of them have been.";
mesg[5] = "</B/24>I hope this little demonstration helps give you an";
mesg[6] = "</B/24>understanding of what the Cdk library offers.";
mesg[7] = " ";
mesg[8] = "<C></B/24>Have fun with it.";
mesg[9] = " ";
mesg[10] = "</B/24>ttfn,";
mesg[11] = "<C></B/24>Mike";
mesg[12] = "<C><#HL(35)>";
mesg[13] = "<R></B/24>March 1996";
popupLabel (screen, (CDK_CSTRING2)mesg, 14);
}
/*
* This deletes a rolodex group.
*/
int deleteRolodexGroup (CDKSCREEN *screen, SRolodex * groupList, int groupCount)
{
/* Declare local variables. */
char *mesg[10];
const char *buttons[5];
char temp[MYSIZE];
int selection, choice, x;
/* If there are no groups, pop up a message telling them. */
if (groupCount == 0)
{
mesg[0] = copyChar ("<C>Error");
mesg[1] = copyChar ("<C>There as no groups defined.");
popupLabel (screen, (CDK_CSTRING2)mesg, 2);
freeCharList (mesg, 2);
/* Return the current group count. */
return groupCount;
}
/* Get the number of the group to delete. */
selection = pickRolodexGroup (screen,
"<C></U>Delete Which Rolodex Group?",
groupList, groupCount);
/* Check the results. */
if (selection < 0)
{
mesg[0] = copyChar ("<C> Delete Canceled ");
mesg[1] = copyChar ("<C>No Group Deleted");
popupLabel (screen, (CDK_CSTRING2)mesg, 2);
freeCharList (mesg, 2);
return groupCount;
}
/* Let's make sure they want to delete the group. */
mesg[0] = copyChar ("<C></U>Confirm Delete");
mesg[1] = copyChar ("<C>Are you sure you want to delete the group");
fmt1s (temp, "<C></R>%.*s<!R>?", groupList[selection].name);
mesg[2] = copyChar (temp);
buttons[0] = "<No>";
buttons[1] = "<Yes>";
choice = popupDialog (screen,
(CDK_CSTRING2)mesg, 3,
(CDK_CSTRING2)buttons, 2);
freeCharList (mesg, 3);
/* Check the results of the confirmation. */
if (choice == 0)
{
mesg[0] = copyChar ("<C> Delete Canceled ");
mesg[1] = copyChar ("<C>No Group Deleted");
popupLabel (screen, (CDK_CSTRING2)mesg, 2);
freeCharList (mesg, 2);
return groupCount;
}
/* We need to delete the group file first. */
unlink (groupList[selection].dbm);
/* OK, lets delete the group. */
freeChar (groupList[selection].name);
freeChar (groupList[selection].desc);
freeChar (groupList[selection].dbm);
for (x = selection; x < groupCount - 1; x++)
{
groupList[x].name = groupList[x + 1].name;
groupList[x].desc = groupList[x + 1].desc;
groupList[x].dbm = groupList[x + 1].dbm;
}
groupCount--;
GGroupModified = 1;
/* Clean up. */
return groupCount;
}
/*
* This function gets information about a new phone number.
*/
int addPhoneRecord (CDKSCREEN *screen, SPhoneData * phoneData)
{
/* Declare local variables. */
CDKLABEL *title;
CDKITEMLIST *itemList;
SPhoneRecord *phoneRecord;
const char *titleMesg[3];
char *types[GLINETYPECOUNT];
char temp[MYSIZE];
int ret, x;
int myType;
/* Get the phone record pointer. */
phoneRecord = &phoneData->record[phoneData->recordCount];
/* Create a title label to display. */
titleMesg[0] = "<C></B/16>Add New Phone Record";
title = newCDKLabel (screen, CENTER, TOP,
(CDK_CSTRING2)titleMesg, 1,
FALSE, FALSE);
drawCDKLabel (title, FALSE);
/* Create the phone line type list. */
for (x = 0; x < GLINETYPECOUNT; x++)
{
fmt1s (temp, "<C></U>%.*s", GLineType[x]);
types[x] = copyChar (temp);
}
/* Get the phone line type. */
itemList = newCDKItemlist (screen, CENTER, CENTER,
"<C>What Type Of Line Is It?",
"Type: ",
(CDK_CSTRING2)types, GLINETYPECOUNT, 0,
TRUE, FALSE);
myType = activateCDKItemlist (itemList, 0);
phoneRecord->lineType = (ELineType) myType;
destroyCDKItemlist (itemList);
/* Clean up. */
for (x = 0; x < GLINETYPECOUNT; x++)
{
freeChar (types[x]);
}
/* Check the return code of the line type question. */
if (phoneRecord->lineType == -1)
{
phoneRecord->lineType = (ELineType) 0;
return 1;
}
else if (phoneRecord->lineType == vPager || phoneRecord->lineType == vCell)
{
ret = getSmallPhoneRecord (screen, phoneRecord);
}
else
{
ret = getLargePhoneRecord (screen, phoneRecord);
}
/* Check the return value from the getXXXPhoneRecord function. */
if (ret == 0)
{
phoneData->recordCount++;
}
/* Clean up. */
destroyCDKLabel (title);
/* Return the new phone list count. */
return ret;
}
/*
* This gets a phone record with all of the details.
*/
int getLargePhoneRecord (CDKSCREEN *screen, SPhoneRecord * phoneRecord)
{
/* Declare local variables. */
CDKENTRY *nameEntry, *addressEntry, *cityEntry;
CDKENTRY *provEntry, *postalEntry, *descEntry;
CDKTEMPLATE *phoneTemplate;
const char *buttons[5];
const char *mesg[15];
/* Define the widgets. */
nameEntry = newCDKEntry (screen, LEFT, 5,
0, "</B/5>Name: ",
A_NORMAL,
'_', vMIXED, 20, 2, MYSIZE,
TRUE, FALSE);
addressEntry = newCDKEntry (screen, RIGHT, 5,
0, "</B/5>Address: ",
A_NORMAL,
'_', vMIXED, 40, 2, MYSIZE,
TRUE, FALSE);
cityEntry = newCDKEntry (screen, LEFT, 8,
0, "</B/5>City: ",
A_NORMAL,
'_', vMIXED, 20, 2, MYSIZE,
TRUE, FALSE);
provEntry = newCDKEntry (screen, 29, 8,
0, "</B/5>Province: ",
A_NORMAL,
'_', vMIXED, 15, 2, MYSIZE,
TRUE, FALSE);
postalEntry = newCDKEntry (screen, RIGHT, 8,
0, "</B/5>Postal Code: ",
A_NORMAL,
'_', vUMIXED, 8, 2, MYSIZE,
TRUE, FALSE);
phoneTemplate = newCDKTemplate (screen, LEFT, 11,
0,
"</B/5>Number: ",
"(###) ###-####",
"(___) ___-____",
TRUE, FALSE);
descEntry = newCDKEntry (screen, RIGHT, 11,
0,
"</B/5>Description: ",
A_NORMAL,
'_', vMIXED, 20, 2, MYSIZE,
TRUE, FALSE);
/* Get the phone information. */
for (;;)
{
int ret;
/* Draw the widgets on the screen. */
drawCDKEntry (nameEntry, ObjOf (nameEntry)->box);
drawCDKEntry (addressEntry, ObjOf (addressEntry)->box);
drawCDKEntry (cityEntry, ObjOf (cityEntry)->box);
drawCDKEntry (provEntry, ObjOf (provEntry)->box);
drawCDKEntry (postalEntry, ObjOf (postalEntry)->box);
drawCDKTemplate (phoneTemplate, ObjOf (phoneTemplate)->box);
drawCDKEntry (descEntry, ObjOf (descEntry)->box);
/* Activate the entries to get the information. */
/* *INDENT-EQLS* */
phoneRecord->name = copyChar (activateCDKEntry (nameEntry, 0));
phoneRecord->address = copyChar (activateCDKEntry (addressEntry, 0));
phoneRecord->city = copyChar (activateCDKEntry (cityEntry, 0));
phoneRecord->province = copyChar (activateCDKEntry (provEntry, 0));
phoneRecord->postalCode = copyChar (activateCDKEntry (postalEntry, 0));
activateCDKTemplate (phoneTemplate, 0);
phoneRecord->phoneNumber = mixCDKTemplate (phoneTemplate);
phoneRecord->desc = copyChar (activateCDKEntry (descEntry, 0));
/* Determine if the user wants to submit the info. */
mesg[0] = "<C></U>Confirm New Phone Entry";
mesg[1] = "<C>Do you want to add this phone number?";
buttons[0] = "</B/24><Add Phone Number>";
buttons[1] = "</B/16><Cancel>";
buttons[2] = "</B/32><Modify Information>";
ret = popupDialog (screen,
(CDK_CSTRING2)mesg, 2,
(CDK_CSTRING2)buttons, 3);
/* Check the response of the popup dialog box. */
if (ret == 0)
{
/* The user wants to submit the information. */
destroyCDKEntry (nameEntry);
destroyCDKEntry (addressEntry);
destroyCDKEntry (cityEntry);
destroyCDKEntry (provEntry);
destroyCDKEntry (postalEntry);
destroyCDKEntry (descEntry);
destroyCDKTemplate (phoneTemplate);
return ret;
}
else if (ret == 1)
{
/* The user does not want to submit the information. */
freeChar (phoneRecord->name);
freeChar (phoneRecord->address);
freeChar (phoneRecord->city);
freeChar (phoneRecord->province);
freeChar (phoneRecord->postalCode);
freeChar (phoneRecord->phoneNumber);
freeChar (phoneRecord->desc);
destroyCDKEntry (nameEntry);
destroyCDKEntry (addressEntry);
destroyCDKEntry (cityEntry);
destroyCDKEntry (provEntry);
destroyCDKEntry (postalEntry);
destroyCDKEntry (descEntry);
destroyCDKTemplate (phoneTemplate);
return ret;
}
else
{
/* The user wants to edit the information again. */
freeChar (phoneRecord->name);
freeChar (phoneRecord->address);
freeChar (phoneRecord->city);
freeChar (phoneRecord->province);
freeChar (phoneRecord->postalCode);
freeChar (phoneRecord->phoneNumber);
freeChar (phoneRecord->desc);
}
}
}
/*
* This gets a small phone record.
*/
int getSmallPhoneRecord (CDKSCREEN *screen, SPhoneRecord * phoneRecord)
{
CDKENTRY *nameEntry, *descEntry;
CDKTEMPLATE *phoneTemplate;
const char *buttons[5];
const char *mesg[15];
/* Define the widgets. */
nameEntry = newCDKEntry (screen, CENTER, 8,
0, "</B/5>Name: ",
A_NORMAL,
'_', vMIXED, 20, 2, MYSIZE,
TRUE, FALSE);
phoneTemplate = newCDKTemplate (screen, CENTER, 11,
0, "</B/5>Number: ",
"(###) ###-####",
"(___) ___-____",
TRUE, FALSE);
descEntry = newCDKEntry (screen, CENTER, 14,
0, "</B/5>Description: ",
A_NORMAL,
'_', vMIXED, 20, 2, MYSIZE,
TRUE, FALSE);
/* Get the phone information. */
for (;;)
{
int ret;
/* Draw the widgets on the screen. */
drawCDKEntry (nameEntry, ObjOf (nameEntry)->box);
drawCDKTemplate (phoneTemplate, ObjOf (phoneTemplate)->box);
drawCDKEntry (descEntry, ObjOf (descEntry)->box);
/* Activate the entries to get the information. */
/* *INDENT-EQLS* */
phoneRecord->name = copyChar (activateCDKEntry (nameEntry, 0));
activateCDKTemplate (phoneTemplate, 0);
phoneRecord->phoneNumber = mixCDKTemplate (phoneTemplate);
phoneRecord->desc = copyChar (activateCDKEntry (descEntry, 0));
phoneRecord->address = copyChar ("-");
phoneRecord->city = copyChar ("-");
phoneRecord->province = copyChar ("-");
phoneRecord->postalCode = copyChar ("-");
/* Determine if the user wants to submit the info. */
mesg[0] = "<C></B/5>Confirm New Phone Entry";
mesg[1] = "<C>Do you want to add this phone number?";
buttons[0] = "</B/24><Add Phone Number>";
buttons[1] = "</B/16><Cancel>";
buttons[2] = "</B/8><Modify Information>";
ret = popupDialog (screen,
(CDK_CSTRING2)mesg, 2,
(CDK_CSTRING2)buttons, 3);
/* Check the response of the popup dialog box. */
if (ret == 0)
{
/* The user wants to submit the information. */
destroyCDKEntry (nameEntry);
destroyCDKEntry (descEntry);
destroyCDKTemplate (phoneTemplate);
return ret;
}
else if (ret == 1)
{
/* The user does not want to submit the information. */
freeChar (phoneRecord->name);
freeChar (phoneRecord->phoneNumber);
freeChar (phoneRecord->desc);
freeChar (phoneRecord->address);
freeChar (phoneRecord->city);
freeChar (phoneRecord->province);
freeChar (phoneRecord->postalCode);
destroyCDKEntry (nameEntry);
destroyCDKEntry (descEntry);
destroyCDKTemplate (phoneTemplate);
return ret;
}
else
{
/* The user wants to edit the information again. */
freeChar (phoneRecord->name);
freeChar (phoneRecord->phoneNumber);
freeChar (phoneRecord->desc);
freeChar (phoneRecord->address);
freeChar (phoneRecord->city);
freeChar (phoneRecord->province);
freeChar (phoneRecord->postalCode);
}
}
}
/*
* This prints a groups phone numbers.
*/
void printGroupNumbers (CDKSCREEN *screen, SRolodex * groupList, int groupCount)
{
/* Declare local variables. */
CDKSELECTION *selectionList;
CDKENTRY *entry;
CDKLABEL *title;
char *itemList[MAX_ITEMS], *mesg[10], temp[MYSIZE];
const char *choices[] =
{
"Print to Printer ",
"Print to File",
"Don't Print"
};
char *filename = 0;
char *printer = 0;
char *defaultPrinter = 0;
int height = groupCount;
int x;
/* Create the group list. */
for (x = 0; x < groupCount; x++)
{
itemList[x] = copyChar (groupList[x].name);
}
/* Set the height of the selection list. */
if (groupCount > 5)
{
height = 5;
}
height += 3;
/* Create the selection list. */
selectionList = newCDKSelection (screen, CENTER, CENTER, RIGHT,
height, 40,
"<C></U>Select Which Groups To Print",
(CDK_CSTRING2)itemList, groupCount,
(CDK_CSTRING2)choices, 3,
A_REVERSE, TRUE, FALSE);
/* Activate the selection list. */
if (activateCDKSelection (selectionList, 0) == -1)
{
/* Tell the user they exited early. */
destroyCDKSelection (selectionList);
mesg[0] = copyChar ("<C>Print Canceled.");
popupLabel (screen, (CDK_CSTRING2)mesg, 1);
freeCharList (mesg, 1);
freeCharList (itemList, (unsigned)groupCount);
return;
}
eraseCDKSelection (selectionList);
/* Determine which groups we want to print. */
for (x = 0; x < groupCount; x++)
{
if (selectionList->selections[x] == 0)
{
/* Create a title. */
fmt1s (temp, "<C></R>Printing Group [%.*s] to Printer",
groupList[x].name);
mesg[0] = copyChar (temp);
title = newCDKLabel (screen, CENTER, TOP,
(CDK_CSTRING2)mesg, 1,
FALSE, FALSE);
drawCDKLabel (title, FALSE);
freeChar (mesg[0]);
/* Get the printer name to print to. */
entry = newCDKEntry (screen, CENTER, 8,
0, "</R>Printer Name: ",
A_NORMAL,
'_', vMIXED, 20, 2, MYSIZE, TRUE, FALSE);
/* Set the printer name to the default printer. */
defaultPrinter = getenv ("PRINTER");
setCDKEntry (entry, defaultPrinter, 2, MYSIZE, TRUE);
printer = copyChar (activateCDKEntry (entry, 0));
destroyCDKEntry (entry);
/* Print the group. */
if (printGroup (groupList[x], "/tmp/rolodex.tmp", printer) == 0)
{
/* The group could not be printed. */
fmt1s (temp, "<C>Sorry the group '%.*s' could not be printed.",
groupList[x].name);
mesg[0] = strdup (temp);
popupLabel (screen, (CDK_CSTRING2)mesg, 1);
freeChar (mesg[0]);
}
/* Clean up. */
destroyCDKLabel (title);
freeChar (printer);
unlink ("/tmp/rolodex.tmp");
}
else if (selectionList->selections[x] == 1)
{
/* Create a title. */
fmt1s (temp, "<C></R>Printing Group [%.*s] to File", groupList[x].name);
mesg[0] = copyChar (temp);
title = newCDKLabel (screen, CENTER, TOP,
(CDK_CSTRING2)mesg, 1,
FALSE, FALSE);
drawCDKLabel (title, FALSE);
freeChar (mesg[0]);
/* Get the filename to print to. */
entry = newCDKEntry (screen, CENTER, 8,
0, "</R>Filename: ",
A_NORMAL, '_', vMIXED,
20, 2, MYSIZE, TRUE, FALSE);
filename = copyChar (activateCDKEntry (entry, 0));
destroyCDKEntry (entry);
/* Print the group. */
if (printGroup (groupList[x], filename, printer) == 0)
{
/* The group could not be printed. */
fmt1s (temp, "<C>Sorry the group '%.*s' could not be printed.",
groupList[x].name);
mesg[0] = strdup (temp);
popupLabel (screen, (CDK_CSTRING2)mesg, 1);
freeChar (mesg[0]);
}
/* Clean up. */
destroyCDKLabel (title);
freeChar (filename);
}
}
/* Clean up. */
destroyCDKSelection (selectionList);
for (x = 0; x < groupCount; x++)
{
freeChar (itemList[x]);
}
}
/*
* This actually prints the phone record.
*/
int printGroup (SRolodex groupRecord, const char *filename, char *printer)
{
/* Declare local variables. */
#if defined (__MINGW32__)
int uid = 0;
#else
uid_t uid = getuid ();
#endif
char tempFilename[MYSIZE];
SPhoneData phoneData;
int phoneCount, x;
FILE *fd;
/* Read the data file. */
phoneCount = readPhoneDataFile (groupRecord.dbm, &phoneData);
/* Create the temporary filename. */
if (filename != 0)
{
fmt1s (tempFilename, "%.*s", filename);
}
else
{
sprintf (tempFilename, "/tmp/rolodex.%d", (int)uid);
}
/* Open the file. */
if ((fd = fopen (tempFilename, "a+")) == 0)
{
/* Clean up. */
for (x = 0; x < phoneCount; x++)
{
freeChar (phoneData.record[x].name);
freeChar (phoneData.record[x].phoneNumber);
freeChar (phoneData.record[x].address);
freeChar (phoneData.record[x].city);
freeChar (phoneData.record[x].province);
freeChar (phoneData.record[x].postalCode);
freeChar (phoneData.record[x].desc);
}
return 0;
}
/* Start writing the group information to the temp file. */
fprintf (fd, "Group Name: %40s\n", groupRecord.name);
fprintf (fd,
"==============================================================================\n");
for (x = 0; x < phoneCount; x++)
{
SPhoneRecord *phoneRecord = &phoneData.record[x];
fprintf (fd, "Name : %s\n", phoneRecord->name);
fprintf (fd, "Phone Number: %s (%s)\n", phoneRecord->phoneNumber,
GLineType[phoneRecord->lineType]);
if (phoneRecord->lineType != vPager && phoneRecord->lineType != vCell)
{
fprintf (fd, "Address : %-20s, %-20s\n", phoneRecord->address, phoneRecord->city);
fprintf (fd, " : %-10s, %-10s\n", phoneRecord->province, phoneRecord->postalCode);
}
fprintf (fd, "Description : %-30s\n", phoneRecord->desc);
fprintf (fd,
"------------------------------------------------------------------------------\n");
}
/* Determine if the information is going to a file or printer. */
if (printer != 0)
{
char command[MYSIZE];
/* Print the file to the given printer. */
sprintf (command, "lpr -P%s %s", printer, tempFilename);
system (command);
/* We have to unkink the temp file. */
unlink (tempFilename);
}
/* Clean up some memory. */
for (x = 0; x < phoneCount; x++)
{
freeChar (phoneData.record[x].name);
freeChar (phoneData.record[x].phoneNumber);
freeChar (phoneData.record[x].address);
freeChar (phoneData.record[x].city);
freeChar (phoneData.record[x].province);
freeChar (phoneData.record[x].postalCode);
freeChar (phoneData.record[x].desc);
}
/* Close the filename. */
fclose (fd);
return 1;
}
/*
****************************************************************
* Start of callback functions.
****************************************************************
*/
int entryPreProcessCB (EObjectType cdkType GCC_UNUSED, void *object
GCC_UNUSED, void *clientData GCC_UNUSED, chtype input)
{
if (input == ' ')
{
Beep ();
return 0;
}
return 1;
}
/*
* This allows the user to insert a new phone entry into the database.
*/
int insertPhoneEntryCB (EObjectType cdkType GCC_UNUSED, void *object, void
*clientData, chtype key GCC_UNUSED)
{
/* Declare local variables. */
CDKSCROLL *scrollp = (CDKSCROLL *)object;
SPhoneData *phoneData = (SPhoneData *) clientData;
SPhoneRecord *phoneRecord = &phoneData->record[phoneData->recordCount];
char temp[MYSIZE];
/* Make the scrolling list disappear. */
eraseCDKScroll (scrollp);
/* Call the function which gets phone record information. */
if (addPhoneRecord (ScreenOf (scrollp), phoneData) == 0)
{
sprintf (temp, "%s (%s)", phoneRecord->name, GLineType[phoneRecord->lineType]);
addCDKScrollItem (scrollp, temp);
}
/* Redraw the scrolling list. */
drawCDKScroll (scrollp, ObjOf (scrollp)->box);
return (FALSE);
}
/*
* This allows the user to delete a phone entry from the database.
*/
int deletePhoneEntryCB (EObjectType cdkType GCC_UNUSED, void *object, void
*clientData, chtype key GCC_UNUSED)
{
/* Declare local variables. */
CDKSCROLL *scrollp = (CDKSCROLL *)object;
SPhoneData *phoneData = (SPhoneData *) clientData;
const char *mesg[3];
char temp[MYSIZE], *hold;
const char *buttons[] =
{
"</B/16><No>",
"</B/24><Yes>"
};
int position = scrollp->currentItem;
int x;
/* Make the scrolling list disappear. */
eraseCDKScroll (scrollp);
/* Check the number of entries left in the list. */
if (scrollp->listSize == 0)
{
mesg[0] = "There are no more numbers to delete.";
popupLabel (ScreenOf (scrollp), (CDK_CSTRING2)mesg, 1);
return (FALSE);
}
/* Ask the user if they really want to delete the listing. */
mesg[0] = "<C>Do you really want to delete the phone entry";
hold = chtype2Char (scrollp->item[scrollp->currentItem]);
fmt1s (temp, "<C></B/16>%.*s", hold);
freeChar (hold);
mesg[1] = copyChar (temp);
if (popupDialog (ScreenOf (scrollp),
(CDK_CSTRING2)mesg, 2,
(CDK_CSTRING2)buttons, 2) == 1)
{
/* Remove the item from the phone data record. */
for (x = position; x < phoneData->recordCount - 1; x++)
{
/* *INDENT-EQLS* */
phoneData->record[x].name = phoneData->record[x + 1].name;
phoneData->record[x].lineType = phoneData->record[x + 1].lineType;
phoneData->record[x].phoneNumber = phoneData->record[x + 1].phoneNumber;
phoneData->record[x].address = phoneData->record[x + 1].address;
phoneData->record[x].city = phoneData->record[x + 1].city;
phoneData->record[x].province = phoneData->record[x + 1].province;
phoneData->record[x].postalCode = phoneData->record[x + 1].postalCode;
phoneData->record[x].desc = phoneData->record[x + 1].desc;
}
phoneData->recordCount--;
/* Nuke the entry. */
deleteCDKScrollItem (scrollp, position);
}
/* Redraw the scrolling list. */
drawCDKScroll (scrollp, ObjOf (scrollp)->box);
return (FALSE);
}
/*
* This function provides help for the phone list editor.
*/
int phoneEntryHelpCB (EObjectType cdkType GCC_UNUSED, void *object, void
*clientData GCC_UNUSED, chtype key GCC_UNUSED)
{
/* Declare local variables. */
CDKSCROLL *scrollp = (CDKSCROLL *)object;
char *mesg[10], temp[100];
/* Create the help title. */
sprintf (temp, "<C></R>Rolodex Phone Editor");
mesg[0] = copyChar (temp);
sprintf (temp, "<B=i > Inserts a new phone entry.");
mesg[1] = copyChar (temp);
sprintf (temp, "<B=d > Deletes the currently selected phone entry.");
mesg[2] = copyChar (temp);
sprintf (temp, "<B=Escape> Exits the scrolling list.");
mesg[3] = copyChar (temp);
sprintf (temp, "<B=? > Pops up this help window.");
mesg[4] = copyChar (temp);
popupLabel (ScreenOf (scrollp), (CDK_CSTRING2)mesg, 5);
freeCharList (mesg, 5);
return (FALSE);
}
/*
* This is a callback to the menu widget. It allows the user to
* ask for help about any sub-menu item.
*/
int helpCB (EObjectType cdkType GCC_UNUSED, void *object, void *clientData
GCC_UNUSED, chtype key GCC_UNUSED)
{
/* *INDENT-EQLS* */
CDKMENU *menu = (CDKMENU *)object;
int menuList = menu->currentTitle;
int submenuList = menu->currentSubtitle;
int selection = ((menuList * 100) + submenuList);
const char *mesg[20];
char *msg_0;
char *name;
char temp[100];
/* Create the help title. */
name = chtype2Char (menu->sublist[menuList][submenuList]);
stripWhiteSpace (vBOTH, name);
fmt1s (temp, "<C></R>Help<!R> </U>%.*s<!U>", name);
mesg[0] = msg_0 = copyChar (temp);
freeChar (name);
/* Set the default value for the message. */
mesg[1] = "<C>No help defined for this menu.";
/* Given the current menu item, create a message. */
if (selection == 0)
{
mesg[1] = "<C>This reads a new rolodex RC file.";
}
else if (selection == 1)
{
mesg[1] = "<C>This saves the current group information in the default RC file.";
}
else if (selection == 2)
{
mesg[1] = "<C>This saves the current group information in a new RC file.";
}
else if (selection == 3)
{
mesg[1] = "<C>This exits this program.";
}
else if (selection == 100)
{
mesg[1] = "<C>This creates a new rolodex group.";
}
else if (selection == 101)
{
mesg[1] = "<C>This opens a rolodex group.";
}
else if (selection == 102)
{
mesg[1] = "<C>This deletes a rolodex group.";
}
else if (selection == 200)
{
mesg[1] = "<C>This prints out selected groups phone numbers.";
}
else if (selection == 300)
{
mesg[1] = "<C>This gives a little history on this program.";
}
else if (selection == 301)
{
mesg[1] = "<C>This provides information about the rolodex.";
}
/* Pop up the message. */
popupLabel (ScreenOf (menu), (CDK_CSTRING2)mesg, 2);
freeChar (msg_0);
/* Redraw the submenu window. */
drawCDKMenuSubwin (menu);
return (FALSE);
}
/*
* This is a callback to the group list scrolling list.
*/
int groupInfoCB (EObjectType cdkType GCC_UNUSED, void *object, void
*clientData, chtype key GCC_UNUSED)
{
/* *INDENT-EQLS* */
CDKSCROLL *scrollp = (CDKSCROLL *)object;
SRolodex *groupList = (SRolodex *) clientData;
int selection = scrollp->currentItem;
char *mesg[5];
char temp[100];
/* Create the message to be displayed. */
mesg[0] = copyChar ("<C></U>Detailed Group Information.");
fmt1s (temp, "</R>Group Name <!R> %.*s", groupList[selection].name);
mesg[1] = copyChar (temp);
fmt1s (temp, "</R>Group Description <!R> %.*s", groupList[selection].desc);
mesg[2] = copyChar (temp);
fmt1s (temp, "</R>Group Database File<!R> %.*s", groupList[selection].dbm);
mesg[3] = copyChar (temp);
/* Display the message. */
popupLabel (ScreenOf (scrollp), (CDK_CSTRING2)mesg, 4);
freeCharList (mesg, 4);
/* Redraw the scrolling list. */
drawCDKScroll (scrollp, ObjOf (scrollp)->box);
return (FALSE);
}