/****************************************************************************** * * NSSDC/CDF CDFedit, part 1 (attributes/entries). * * Version 1.3c, 16-Nov-97, Hughes STX. * * Modification history: * * V1.0 24-Jan-94, J Love Original version. * V1.0a 4-Feb-94, J Love DEC Alpha/OpenVMS port. * V1.0b 22-Feb-94, J Love Spelling lesson. * V1.1 15-Dec-94, J Love CDF V2.5. * V1.1a 23-Jan-95, J Love IRIX 6.x (64-bit). * V1.1b 28-Feb-95, J Love Solaris 2.3. Pass `char' as `int'. * V1.2 11-Apr-95, J Love POSIX. * V1.2a 11-May-95, J Love EPOCH styles. * V1.2b 9-Jun-95, J Love catchrX. * V1.2c 6-Sep-95, J Love CDFexport-related changes. FSI key * definitions. * V1.3 30-Sep-96, J Love CDF V2.6. * V1.3a 19-Dec-96, J Love Display error if attempt to browse/edit a * vAttribute's entries in "text mode" is made. * V1.3b 2-Sep-97, J Love Fixed attribute name declaration. * V1.3c 16-Nov-97, J Love Windows NT/Visual C++. * ******************************************************************************/ #include "cdfedit.h" /****************************************************************************** * EditAttrs. ******************************************************************************/ Logical EditAttrs (G, CDFname) Logical G; /* If TRUE, global scoped attributes. */ char *CDFname; /* Name of the CDF being edited. */ { CDFstatus status; int attrX, entryX, entryType; long attrN, entryN, fieldN, *nEntries, *attrNs, **entryNs; long nAttrs; /* Number of attributes of the proper scope. */ AOSs2 (header, BLANKs78, BLANKs78) AOSs1 (trailerBrowse, "Select: ________ Exit: ________ Help: ________") AOSs3 (trailerEdit, "Select: ________ Create attribute: ________ Delete attribute/entry: ________", "Help: ________ Create entry: ________", "Exit: ________ Toggle scope: ________") static int exitCharsBrowse[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static int exitCharsEdit[] = { ENTERkey_FSI, CREATEATTRkey_EDIT, EXITkey_FSI, HELPkey_FSI, CREATEENTRYkey_EDIT, TOGGLESCOPEkey_EDIT, DELETEATTRorENTRYkey_EDIT, NUL }; static char label[6+DU_MAX_NAME_LEN+14+1]; static struct ItemWindowStruct IW = { 0, 0, 80, label, 2, header, 0, NULL, 0, NULL, NULL, NULL, 0, 0, NULL, NULL, REFRESHkey_FSI, TRUE, NSkey_FSI, PSkey_FSI }; static Logical first = TRUE; /*************************************************************************** * First time... ***************************************************************************/ if (first) { EncodeKeyDefinitions (1, trailerBrowse, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); EncodeKeyDefinitions (3, trailerEdit, ENTERkey_FSI, CREATEATTRkey_EDIT, DELETEATTRorENTRYkey_EDIT, HELPkey_FSI, CREATEENTRYkey_EDIT, EXITkey_FSI, TOGGLESCOPEkey_EDIT); first = FALSE; } if (browseOnly) { IW.NiRows = 14; IW.NtLines = 1; IW.tLines = trailerBrowse; IW.exitChars = exitCharsBrowse; } else { IW.NiRows = 12; IW.NtLines = 3; IW.tLines = trailerEdit; IW.exitChars = exitCharsEdit; } /*************************************************************************** * Build attribute/entry lines and display menu. ***************************************************************************/ if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) return FALSE; ItemWindow (NEWiw, &IW, 0); /*************************************************************************** * Read/process keystrokes until request to exit menu. ***************************************************************************/ for (;;) { ItemWindow (READiw, &IW); switch (IW.key) { /*********************************************************************** * Item selected. ***********************************************************************/ case ENTERkey_FSI: { int nameItemN; /********************************************************************* * Check if any attributes/entries exist. *********************************************************************/ if (IW.nItems == 0) { ProblemWindow (BOO(G,"Nothing selected (no gAttributes exist).", "Nothing selected (no vAttributes exist)."), FALSE); break; } /********************************************************************* * Calculate attribute, entry, and field numbers. *********************************************************************/ for (attrX = 0, nameItemN = 0; attrX < nAttrs; attrX++) { int nItems = (int) (1 + (4 * nEntries[attrX])); if (IW.itemN < nameItemN + nItems) { int itemNt = IW.itemN - nameItemN; attrN = attrNs[attrX]; if (itemNt == 0) fieldN = 0; else { fieldN = ((itemNt - 1) % 4) + 1; entryX = (itemNt - 1) / 4; entryN = entryNs[attrX][entryX]; if (G) entryType = gENTRYt; else { long NrEntries; status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NUMrENTRIES_, &NrEntries, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } entryType = (entryX < NrEntries ? rENTRYt : zENTRYt); } } break; } nameItemN += nItems; } /********************************************************************* * Perform desired function (based on field number). *********************************************************************/ switch (fieldN) { /******************************************************************* * Modify attribute name. *******************************************************************/ case 0: { char attrName[CDF_ATTR_NAME_LEN256+1]; status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (browseOnly) ShowFullName (attrName, TRUE); else { static char *header[] = { "Enter new name (with delimiters)...", "Syntax: ...", "Example: \"FILTERs\"" }; AOSs1 (trailer, "Enter: ________ Exit: ________ Help: ________") static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static char value[1+CDF_ATTR_NAME_LEN256+1+1]; static char label[15+CDF_ATTR_NAME_LEN256+1]; static struct PromptWindowStruct PWt = { label, 4, 1, 78, 3, header, CDF_ATTR_NAME_LEN256+2, value, 1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; char delim; EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); delim = PickDelimiter (attrName, strlen(attrName)); sprintf (value, "%c%s%c", delim, attrName, delim); sprintf (label, " %cAttribute %c%s%c ", BOO(G,'g','v'), delim, attrName, delim); PromptWindow (NEWpw, &PWt, (int) (strlen(PWt.value) - 1), LogicalTRUE); for (;;) { if (EnterPW(&PWt,ATTRRENAMEhelpID)) { char attrName[CDF_ATTR_NAME_LEN256+1]; if (DecodeDelimitedString(PWt.value,attrName)) { status = CDFlib (PUT_, ATTR_NAME_, attrName, NULL_); if (ReportStatus(status,FALSE)) { FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); break; } if (NoMoreAccess(NULL)) { PromptWindow (DELETEpw, &PWt); ItemWindow (DELETEiw, &IW); return FALSE; } } else ProblemWindow ("Illegal name (check delimiters).", FALSE); } else break; } PromptWindow (DELETEpw, &PWt); } break; } /******************************************************************* * Modify variable name/global entry number. *******************************************************************/ case 1: { if (G) ItemWindow (BEEPiw, &IW); else { char varName[CDF_VAR_NAME_LEN256+1]; Logical Z = (entryType == zENTRYt); long nVars; status = CDFlib (GET_, BOO(Z,CDF_NUMzVARS_, CDF_NUMrVARS_), &nVars, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (nVars <= entryN) { ProblemWindow (BOO(Z,"No corresponding zVariable.", "No corresponding rVariable."), FALSE); break; } status = CDFlib (SELECT_, VAR(Z), entryN, GET_, VAR_NAME(Z), varName, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (browseOnly) ShowFullName (varName, FALSE); else { static char *header[] = { "Enter new name (with delimiters)...", "Syntax: ...", "Example: \"Humidity\"" }; AOSs1 (trailer, "Enter: ________ Exit: ________ Help: ________") static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static char value[1+CDF_VAR_NAME_LEN256+1+1]; static char label[14+CDF_VAR_NAME_LEN256+1]; static struct PromptWindowStruct PWt = { label, 4, 1, 78, 3, header, CDF_VAR_NAME_LEN256+2, value, 1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; char delim; EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); delim = PickDelimiter (varName, strlen(varName)); sprintf (value, "%c%s%c", delim, varName, delim); sprintf (label, " %cVariable %c%s%c ", BOO(Z,'z','r'), delim, varName, delim); PromptWindow (NEWpw, &PWt, (int) (strlen(PWt.value) - 1), LogicalTRUE); for (;;) { if (EnterPW(&PWt,VARRENAMEhelpID)) { char varName[CDF_VAR_NAME_LEN256+1]; if (DecodeDelimitedString(PWt.value,varName)) { status = CDFlib (PUT_, VAR_NAME(Z), varName, NULL_); if (ReportStatus(status,FALSE)) { FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); break; } if (NoMoreAccess(NULL)) { PromptWindow (DELETEpw, &PWt); ItemWindow (DELETEiw, &IW); return FALSE; } } else ProblemWindow ("Illegal name (check delimiters).", FALSE); } else break; } PromptWindow (DELETEpw, &PWt); } } break; } /******************************************************************* * Modify data specification. *******************************************************************/ case 2: { if (browseOnly) ItemWindow (BEEPiw, &IW); else { long dataType, numElems; if (G) sprintf (label, " gEntry %ld ", entryN + 1); else { Logical Z = (entryType == zENTRYt); char varName[CDF_VAR_NAME_LEN256+1], delim; status = CDFlib (SELECT_, VAR(Z), entryN, GET_, VAR_NAME(Z), varName, NULL_); switch (status) { case NO_SUCH_VAR: sprintf (label," %cEntry %ld ",BOO(Z,'z','r'),entryN+1); break; default: if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } delim = PickDelimiter (varName, strlen(varName)); sprintf (label, " %cEntry for %c%s%c ", BOO(Z,'z','r'), delim, varName, delim); break; } } status = CDFlib (SELECT_, ATTR_, attrN, ENTRY(entryType), entryN, GET_, ENTRY_DATATYPE(entryType), &dataType, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (SelectDataSpec(&dataType,NULL,label)) { status = CDFlib (GET_, ENTRY_NUMELEMS(entryType), &numElems, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } status = CDFlib (PUT_, ENTRY_DATASPEC(entryType), dataType, numElems, NULL_); if (ReportStatus(status,FALSE)) { FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); break; } if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } } break; } /******************************************************************* * Modify data specification/value(s). *******************************************************************/ case 3: { if (browseOnly) ItemWindow (BEEPiw, &IW); else { Logical changed = FALSE; if (!EditEntry(attrN,entryN,entryType,TRUE,&changed)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (changed) { FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); } } break; } /******************************************************************* * Modify value(s). *******************************************************************/ case 4: { Logical changed = FALSE; if (!EditEntry(attrN,entryN,entryType,FALSE,&changed)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (changed) { FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); } break; } } break; } /*********************************************************************** * Create new attribute. ***********************************************************************/ case CREATEATTRkey_EDIT: { static char *header[] = { "Enter name (with delimiters)...", "Syntax: ...", "Example: \"Resolution\"" }; AOSs1 (trailer, "Enter: ________ Exit: ________ Help: ________") static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static char value[DELIMed_ATTR_NAME_LEN+1]; static char label[16+1]; static struct PromptWindowStruct PWt = { label, 4, 1, 78, 3, header, CDF_ATTR_NAME_LEN256+2, value, 1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); strcpyX (value, "\"\"", DELIMed_ATTR_NAME_LEN); sprintf (label, " New %cAttribute ", BOO(G,'g','v')); PromptWindow (NEWpw, &PWt, 1, LogicalTRUE); for (;;) { if (EnterPW(&PWt,ATTRNAMEhelpID)) { char attrName[CDF_ATTR_NAME_LEN256+1]; long attrNum; if (DecodeDelimitedString(PWt.value,attrName)) { status = CDFlib (CREATE_, ATTR_, attrName, BOO(G,GLOBAL_SCOPE, VARIABLE_SCOPE), &attrNum, NULL_); if (ReportStatus(status,FALSE)) { FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.nItems - 1); break; } if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } else ProblemWindow ("Illegal name (check delimiters).", FALSE); } else break; } PromptWindow (DELETEpw, &PWt); break; } /*********************************************************************** * Create new entry. ***********************************************************************/ case CREATEENTRYkey_EDIT: { int nameItemN; Logical changed = FALSE; if (IW.nItems == 0) { ProblemWindow(BOO(G,"A gAttribute isn't selected (none exist).", "A vAttribute isn't selected (none exist)."), FALSE); break; } for (attrX = 0, nameItemN = 0; attrX < nAttrs; attrX++) { int nItems = (int) (1 + (4 * nEntries[attrX])); if (IW.itemN < nameItemN + nItems) { attrN = attrNs[attrX]; break; } nameItemN += nItems; } if (!CreateEntry(G,attrN,&changed)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (changed) { FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, nameItemN); } break; } /*********************************************************************** * Delete attribute/entry. ***********************************************************************/ case DELETEATTRorENTRYkey_EDIT: { int nameItemN; Logical deleteAttr; if (IW.nItems == 0) { static char noG[] = { "A gAttribute/gEntry isn't selected (none exist)." }; static char noV[] = { "A vAttribute/entry isn't selected (none exist)." }; ProblemWindow (BOO(G,noG,noV), FALSE); break; } for (attrX = 0, nameItemN = 0; attrX < nAttrs; attrX++) { int nItems = (int) (1 + (4 * nEntries[attrX])); if (IW.itemN < nameItemN + nItems) { int itemNt = IW.itemN - nameItemN; attrN = attrNs[attrX]; if (itemNt == 0) deleteAttr = TRUE; else { deleteAttr = FALSE; entryX = (itemNt - 1) / 4; entryN = entryNs[attrX][entryX]; if (G) entryType = gENTRYt; else { long NrEntries; status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NUMrENTRIES_, &NrEntries, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } entryType = (entryX < NrEntries ? rENTRYt : zENTRYt); } } break; } nameItemN += nItems; } if (deleteAttr) { char attrName[CDF_ATTR_NAME_LEN256+1], question[22+CDF_ATTR_NAME_LEN256+1], delim; status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } delim = PickDelimiter (attrName, strlen(attrName)); sprintf (question, "Delete %sAttribute %c%s%c ?", BOO(G,"g","v"), delim, attrName, delim); if (ConfirmWindow(4,78,question,NULL,FALSE,DELETEATTRhelpID)) { status = CDFlib (DELETE_, ATTR_, NULL_); if (ReportStatus(status,FALSE)) { FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, 0); } else { if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } } } else { char attrName[CDF_ATTR_NAME_LEN256+1], delim = ' ', question1[40+ENTRYNUM_FIELD_LEN+CDF_ATTR_NAME_LEN256+1], question2[31+CDF_VAR_NAME_LEN256+1]; status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (entryType == gENTRYt) { delim = PickDelimiter (attrName, strlen(attrName)); sprintf (question1, "Delete gEntry number %ld of gAttribute %c%s%c ?", entryN + 1, delim, attrName, delim); question2[0] = NUL; } else { char varName[CDF_VAR_NAME_LEN256+1]; status = CDFlib (SELECT_, BOO(entryType==zENTRYt,zVAR_, rVAR_), entryN, GET_, BOO(entryType==zENTRYt, zVAR_NAME_,rVAR_NAME_), varName, NULL_); switch (status) { case NO_SUCH_VAR: sprintf (question1, "Delete %sEntry number %ld of vAttribute %c%s%c ?", BOO(entryType==zENTRYt,"z","r"), entryN + 1, delim, attrName, delim); question2[0] = NUL; break; default: if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } delim = PickDelimiter (attrName, strlen(attrName)); sprintf (question1, "Delete %sEntry of vAttribute %c%s%c", BOO(entryType==zENTRYt,"z","r"), delim, attrName, delim); delim = PickDelimiter (varName, strlen(varName)); sprintf (question2, "corresponding to %sVariable %c%s%c ?", BOO(entryType==zENTRYt,"z","r"), delim, varName, delim); break; } } if (ConfirmWindow(4,78,question1, BOO(NULstring(question2),NULL,question2), FALSE,DELETEENTRYhelpID)) { status = CDFlib (SELECT_, ENTRY(entryType), entryN, DELETE_, ENTRY(entryType), NULL_); if (ReportStatus(status,FALSE)) { FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, 0); } else { if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } } } break; } /*********************************************************************** * Toggle scope. ***********************************************************************/ case TOGGLESCOPEkey_EDIT: { int nameItemN; if (IW.nItems == 0) { ProblemWindow(BOO(G,"A gAttribute isn't selected (none exist).", "A vAttribute isn't selected (none exist)."), FALSE); break; } for (attrX = 0, nameItemN = 0; attrX < nAttrs; attrX++) { int nItems = (int) (1 + (4 * nEntries[attrX])); if (IW.itemN < nameItemN + nItems) { attrN = attrNs[attrX]; break; } nameItemN += nItems; } status = CDFlib (SELECT_,ATTR_,attrN, PUT_,ATTR_SCOPE_,BOO(G,VARIABLE_SCOPE,GLOBAL_SCOPE), NULL_); if (ReportStatus(status,FALSE)) { FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); if (!BuildAttrMenu(G,CDFname,&nAttrs,&attrNs, &nEntries,&entryNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, 0); } else { if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } break; } /*********************************************************************** * Display online help. ***********************************************************************/ case HELPkey_FSI: OnlineHelpWindow (ilhFile, BOO(G,GATTRShelpID,VATTRShelpID)); break; /*********************************************************************** * Exit menu. ***********************************************************************/ case EXITkey_FSI: ItemWindow (DELETEiw, &IW); FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, &IW); return TRUE; } } } /****************************************************************************** * BuildAttrMenu. ******************************************************************************/ Logical BuildAttrMenu (G, CDFname, nAttrs, attrNs, nEntries, entryNs, IW) Logical G; char *CDFname; long *nAttrs; long **attrNs; long **nEntries; long ***entryNs; struct ItemWindowStruct *IW; { CDFstatus status; int attrX, entryX; long dataType, numElems; long NgEntries, NrEntries, NzEntries; char attrName[CDF_ATTR_NAME_LEN256+1]; int curItem; int curCol; int lineN; int n; int dataSpecCol; void *binary; char field[80+1]; long TnAttrs; /* Total number of attributes (global and variable scoped). */ int entryType; int entryXt; int nLines, nItems; long attrN; long estLines; /* Estimated number of lines for the menu. */ AOSs2 (loadingLines, "Loading menu...", "") /*************************************************************************** * Determine number of attributes (total and of proper scope). ***************************************************************************/ status = CDFlib (GET_, CDF_NUMATTRS_, &TnAttrs, BOO(G,CDF_NUMgATTRS_,CDF_NUMvATTRS_), nAttrs, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; if (!G) { long NrVars, NzVars; status = CDFlib (GET_, CDF_NUMrVARS_, &NrVars, CDF_NUMzVARS_, &NzVars, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; estLines = (*nAttrs) * (NrVars + NzVars); if (estLines > MANY_ATTRs_AND_ENTRYs) { MessageWindow (loadingLines, NULL, LogicalFALSE); } } /*************************************************************************** * Count/save attribute and entry numbers. Determine attribute name item * numbers. ***************************************************************************/ *nEntries = (long *) cdf_AllocateMemory ((size_t) (*nAttrs * sizeof(long)), FatalError); *attrNs = (long *) cdf_AllocateMemory ((size_t) (*nAttrs * sizeof(long)), FatalError); *entryNs = (long **) cdf_AllocateMemory ((size_t) (*nAttrs * sizeof(long *)), FatalError); for (attrN=0, attrX=0, nItems=0, nLines=0; attrN < TnAttrs; attrN++) { long scope; /************************************************************************ * Determine scope. ************************************************************************/ status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_SCOPE_, &scope, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /************************************************************************ * If proper scope, save attribute number and determine which entries * exist. ************************************************************************/ if ((G && (scope == GLOBAL_SCOPE)) || (!G && (scope == VARIABLE_SCOPE))) { int i; long entryN; /********************************************************************** * Tally an attribute of the proper scope. **********************************************************************/ (*attrNs)[attrX] = attrN; nItems++; nLines++; /********************************************************************** * Determine number of entries. **********************************************************************/ if (G) { status = CDFlib (GET_, ATTR_NUMgENTRIES_, &NgEntries, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; (*nEntries)[attrX] = NgEntries; } else { status = CDFlib (GET_, ATTR_NUMrENTRIES_, &NrEntries, ATTR_NUMzENTRIES_, &NzEntries, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; (*nEntries)[attrX] = NrEntries + NzEntries; } (*entryNs)[attrX] = (long *) cdf_AllocateMemory ((size_t) ((*nEntries)[attrX] * sizeof(long)), FatalError); for (i = 0, entryX = 0, entryType = BOO(G,gENTRYt,rENTRYt); i < BOO(G,1,2); i++, entryType = zENTRYt) { long nEntries = E3(entryType,NgEntries,NrEntries,NzEntries); for (entryN = 0, entryXt = 0; entryXt < nEntries; entryN++) { status = CDFlib (SELECT_, ENTRY(entryType), entryN, CONFIRM_, CURENTRY_EXISTENCE(entryType), NULL_); switch (status) { case NO_SUCH_ENTRY: break; default: if (!ReportStatus(status,FALSE)) return FALSE; nItems += 4; if (entryX > 0) nLines++; (*entryNs)[attrX][entryX] = entryN; entryX++; entryXt++; break; } } } attrX++; } } /*************************************************************************** * Allocate item section control/lines. ***************************************************************************/ AllocIW (IW, nItems, nLines, 80, FatalError); /*************************************************************************** * Encode label/header. ***************************************************************************/ sprintf (IW->label, " CDF \"%s\" %cAttributes ", CDFname, BOO(G,'g','v')); if (G) { sprintf (IW->hLines[0], "%ld gAttribute%s", *nAttrs, (*nAttrs == 1 ? "" : "s")); strcpyX (IW->hLines[1], "AttrName Entry DataSpec Value(s)", 0); } else { sprintf (IW->hLines[0], "%ld vAttribute%s", *nAttrs, (*nAttrs == 1 ? "" : "s")); strcpyX (IW->hLines[1], "AttrName VarName DataSpec Value(s)", 0); } /*************************************************************************** * Build each attribute/entry line. ***************************************************************************/ lineN = 0; curItem = 0; for (attrX = 0; attrX < *nAttrs; attrX++) { /************************************************************************ * Inquire attribute. ************************************************************************/ status = CDFlib (SELECT_, ATTR_, (*attrNs)[attrX], GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /************************************************************************ * Setup attribute name. ************************************************************************/ curCol = 0; EncodeString (strlen(attrName), attrName, field, 0, ATTRNAME_FIELD_LEN); strcpyX (IW->iLines[lineN], field, 0); if (strlen(field) < (size_t) ATTRNAME_FIELD_LEN) { CatNcharacters (IW->iLines[lineN], ATTRNAME_FIELD_LEN - strlen(field), (int) ' '); } CatNcharacters (IW->iLines[lineN], ATTRNAME_FIELD_BLANKS, (int) ' '); IW->iLineNs[curItem] = lineN; IW->iCols[curItem] = curCol; IW->iLens[curItem] = strlen(field); curCol += ATTRNAME_FIELD_LEN + ATTRNAME_FIELD_BLANKS; curItem++; /************************************************************************ * Setup each entry. ************************************************************************/ if (!G) { status = CDFlib (GET_, ATTR_NUMrENTRIES_, &NrEntries, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; } if ((*nEntries)[attrX] > 0) { for (entryX = 0; entryX < (*nEntries)[attrX]; entryX++) { int entryType = BOO(G,gENTRYt, BOO(entryX < NrEntries,rENTRYt,zENTRYt)); /******************************************************************* * Inquire entry. *******************************************************************/ status = CDFlib (SELECT_,ENTRY(entryType),(*entryNs)[attrX][entryX], GET_, ENTRY_DATATYPE(entryType), &dataType, ENTRY_NUMELEMS(entryType), &numElems, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /******************************************************************* * Pad with blanks the attribute name field if this isn't the first * entry. *******************************************************************/ if (entryX > 0) { strcpyX (IW->iLines[lineN], "", 0); CatNcharacters (IW->iLines[lineN], ATTRNAME_FIELD_LEN, (int) ' '); CatNcharacters (IW->iLines[lineN], ATTRNAME_FIELD_BLANKS, (int) ' '); curCol = ATTRNAME_FIELD_LEN + ATTRNAME_FIELD_BLANKS; } /******************************************************************* * Setup entry number field if global scope, variable name if * variable scope. *******************************************************************/ if (G) { sprintf (field, "%ld", (*entryNs)[attrX][entryX] + 1); if (strlen(field) > (size_t) ENTRYNUM_FIELD_LEN) strcpyX (field + ENTRYNUM_FIELD_LEN - 3, "...", 0); } else { char varName[CDF_VAR_NAME_LEN256+1]; status = CDFlib (SELECT_, E3(entryType,0,rVAR_, zVAR_), (*entryNs)[attrX][entryX], GET_, E3(entryType,0, rVAR_NAME_,zVAR_NAME_), varName, NULL_); switch (status) { case NO_SUCH_VAR: { Logical Z = E3(entryType,FALSE,FALSE,TRUE); sprintf (field, "<%sEntry.%ld>", BOO(Z,"z","r"), (*entryNs)[attrX][entryX] + 1); break; } default: if (!ReportStatus(status,FALSE)) return FALSE; EncodeString (strlen(varName), varName, field, 0, VARNAME_FIELD_LEN); break; } } strcatX (IW->iLines[lineN], field, 0); if (strlen(field) < (size_t) BOO(G,ENTRYNUM_FIELD_LEN, VARNAME_FIELD_LEN)) { CatNcharacters (IW->iLines[lineN], BOO(G,ENTRYNUM_FIELD_LEN, VARNAME_FIELD_LEN) - strlen(field), (int) ' '); } CatNcharacters (IW->iLines[lineN], BOO(G,ENTRYNUM_FIELD_BLANKS,VARNAME_FIELD_BLANKS), (int) ' '); IW->iLineNs[curItem] = lineN; IW->iCols[curItem] = curCol; IW->iLens[curItem] = strlen(field); curCol += BOO(G,ENTRYNUM_FIELD_LEN,VARNAME_FIELD_LEN) + BOO(G,ENTRYNUM_FIELD_BLANKS,VARNAME_FIELD_BLANKS); curItem++; /******************************************************************* * Setup data type & number of elements. *******************************************************************/ strcpyX (field, DataTypeToken(dataType), 0); catchrX (field, (int) '/', 0); sprintf (&field[strlen(field)], "%ld", numElems); if (strlen(field) > (size_t) DATASPEC_FIELD_LEN) { strcpyX (field + DATASPEC_FIELD_LEN - 3, "...", 0); } strcatX (IW->iLines[lineN], field, 0); if (strlen(field) < (size_t) DATASPEC_FIELD_LEN) { CatNcharacters (IW->iLines[lineN], DATASPEC_FIELD_LEN - strlen(field), (int) ' '); } CatNcharacters (IW->iLines[lineN], DATASPEC_FIELD_BLANKS, (int)' '); IW->iLineNs[curItem] = lineN; IW->iCols[curItem] = curCol; IW->iLens[curItem] = strlen(field); dataSpecCol = curCol; curCol += DATASPEC_FIELD_LEN + DATASPEC_FIELD_BLANKS; curItem++; /******************************************************************* * Setup value(s) field. *******************************************************************/ binary = cdf_AllocateMemory ((size_t) (numElems * CDFelemSize(dataType)), FatalError); status = CDFlib (GET_, ENTRY_DATA(entryType), binary, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; n = EncodeValuesFormat (dataType, numElems, binary, &(IW->iLines[lineN][curCol]), NULL, 0, BOO(G,gAttrENTRYVALUE_FIELD_LEN, vAttrENTRYVALUE_FIELD_LEN), EPOCH0_STYLE); cdf_FreeMemory (binary, FatalError); /******************************************************************* * Set 'dataSpec/value' item control information. *******************************************************************/ IW->iLineNs[curItem] = lineN; IW->iCols[curItem] = dataSpecCol; IW->iLens[curItem] = strlen(&(IW->iLines[lineN][dataSpecCol])); curItem++; /******************************************************************* * Set `value' item control information. *******************************************************************/ IW->iLineNs[curItem] = lineN; IW->iCols[curItem] = curCol; IW->iLens[curItem] = n; curItem++; lineN++; } } else { lineN++; /* No entries, just increment to next line. */ } } if (!G) { if (estLines > MANY_ATTRs_AND_ENTRYs) MessageWindow (NULL); } return TRUE; } /****************************************************************************** * FreeAttrMenu. ******************************************************************************/ void FreeAttrMenu (nAttrs, attrNs, nEntries, entryNs, IW) long nAttrs; long *attrNs; long *nEntries; long **entryNs; struct ItemWindowStruct *IW; { int attrX; FreeIW (IW, FatalError); for (attrX = (int) (nAttrs - 1); attrX >= 0; attrX--) { if (entryNs[attrX] != NULL) cdf_FreeMemory (entryNs[attrX], FatalError); } if (entryNs != NULL) cdf_FreeMemory (entryNs, FatalError); if (attrNs != NULL) cdf_FreeMemory (attrNs, FatalError); if (nEntries != NULL) cdf_FreeMemory (nEntries, FatalError); return; } /****************************************************************************** * EditEntry. * Returns FALSE if a fatal CDF error occurred. ******************************************************************************/ Logical EditEntry (attrN, entryN, entryType, newDataSpec, changed) long attrN; long entryN; int entryType; Logical newDataSpec; Logical *changed; /* Assumed to be initialized to FALSE by the caller. */ { long dataType, numElems; int cursorAtThisChar; CDFstatus status; static char value[MAX_ENTRYSTRING_LEN+1]; static char label[15+CDF_VAR_NAME_LEN256+1]; static char *headerBrowse[] = { "Full entry value..." }; static char *headerChar[] = { "Enter character string (with delimiters)...", "Syntax: ..." }; static char *headerNoChar[] = { "Enter value(s)...", "Syntax: ,,...," }; AOSs1A (trailerBrowse, "Exit: ________ Help: ________") AOSs1B (trailerEdit, "Enter: ________ Exit: ________ Help: ________") static int exitCharsBrowse[] = { EXITkey_FSI, HELPkey_FSI, NUL }; static int exitCharsEdit[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static struct PromptWindowStruct PW = { label, 4, 1, 78, 0, NULL, MAX_ENTRYSTRING_LEN, value, 1, NULL, NULL, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; /**************************************************************************** * Encode label. ****************************************************************************/ switch (entryType) { case gENTRYt: sprintf (label, " gEntry %ld ", entryN + 1); break; case rENTRYt: case zENTRYt: { Logical Z = (entryType == zENTRYt); char varName[CDF_VAR_NAME_LEN256+1], delim; status = CDFlib (SELECT_, VAR(Z), entryN, GET_, VAR_NAME(Z), varName, NULL_); switch (status) { case NO_SUCH_VAR: sprintf (label, " %cEntry %ld ", BOO(Z,'z','r'), entryN + 1); break; default: if (!ReportStatus(status,FALSE)) return FALSE; delim = PickDelimiter (varName, strlen(varName)); sprintf (label, " %cEntry for %c%s%c ", BOO(Z,'z','r'), delim, varName, delim); break; } break; } } /**************************************************************************** * Either prompt for a new data type (the number of elements will be implied * by the value entered) or read the current data specification and value. * Note that it should never be necessary to prompt for a new data type when * browsing. ****************************************************************************/ if (!browseOnly && newDataSpec) { dataType = NO_DATATYPE; if (!SelectDataSpec(&dataType,NULL,label)) return TRUE; strcpyX (value, BOO(STRINGdataType(dataType),"\"\"",""), MAX_ENTRYSTRING_LEN); } else { void *binary; status = CDFlib (SELECT_, ATTR_, attrN, ENTRY(entryType), entryN, GET_, ENTRY_DATATYPE(entryType), &dataType, ENTRY_NUMELEMS(entryType), &numElems, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; binary = cdf_AllocateMemory ((size_t) (numElems * CDFelemSize(dataType)), FatalError); status = CDFlib (GET_, ENTRY_DATA(entryType), binary, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; EncodeValuesFormat (dataType, numElems, binary, value, NULL, 0, MAX_ENTRYSTRING_LEN, EPOCH0_STYLE); cdf_FreeMemory (binary, FatalError); } /**************************************************************************** * Prompt for the new value. ****************************************************************************/ if (browseOnly) { EncodeKeyDefinitions (1, trailerBrowse, EXITkey_FSI, HELPkey_FSI); PW.NhLines = 1; PW.hLines = headerBrowse; PW.tLines = trailerBrowse; PW.exitChars = exitCharsBrowse; } else { EncodeKeyDefinitions (1, trailerEdit, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); PW.NhLines = 2; PW.hLines = BOO(STRINGdataType(dataType),headerChar,headerNoChar); PW.tLines = trailerEdit; PW.exitChars = exitCharsEdit; } cursorAtThisChar = BOO(browseOnly,0,strlen(PW.value) - BOO(STRINGdataType(dataType),1,0)); PromptWindow (NEWpw, &PW, cursorAtThisChar, LogicalTRUE); for (;;) { if (EnterPW(&PW,ENTRYVALUEhelpID)) { void *newBinary; long newNumElems; if (DecodeValues(PW.value,dataType,&newNumElems, &newBinary,EPOCH0_STYLE)) { status = CDFlib (SELECT_, ATTR_, attrN, ENTRY(entryType), entryN, PUT_, ENTRY_DATA(entryType), dataType, newNumElems, newBinary, NULL_); cdf_FreeMemory (newBinary, FatalError); if (ReportStatus(status,FALSE)) { *changed = TRUE; break; } if (NoMoreAccess(NULL)) { PromptWindow (DELETEpw, &PW); return FALSE; } } else ProblemWindow ("Error decoding values.", FALSE); } else break; } PromptWindow (DELETEpw, &PW); return TRUE; } /****************************************************************************** * EditVarEntries. ******************************************************************************/ Logical EditVarEntries (Z, varN, nVars) Logical Z; long varN; long nVars; { CDFstatus status; long nAttrs; /* Number of variable scoped attributes. */ long attrN; AOSs2 (header, BLANKs78, BLANKs78) AOSs1 (trailerBrowse, "Select: ________ Exit: ________ Help: ________ Next variable: ________") AOSs3 (trailerEdit, "Select: ________ Create attribute: ________ Next variable: ________", "Exit: ________ Create entry: ________ Delete entry: ________", "Help: ________") static int exitCharsBrowse[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NEXTVARkey_EDIT, NUL }; static int exitCharsEdit[] = { ENTERkey_FSI, EXITkey_FSI, CREATEATTRkey_EDIT, HELPkey_FSI, CREATEENTRYkey_EDIT, DELETEATTRorENTRYkey_EDIT, NEXTVARkey_EDIT, NUL }; static char label[12+CDF_VAR_NAME_LEN256+11+1]; static struct ItemWindowStruct IW = { 0, 0, 80, label, 2, header, 0, NULL, 0, NULL, NULL, NULL, 0, 0, NULL, NULL, REFRESHkey_FSI, TRUE, NSkey_FSI, PSkey_FSI }; long *attrNs; /* Attribute numbers. */ Logical *entryIs; /* TRUE if there is an entry. */ int attrX; /* Attribute index (which variable scoped attribute). */ static Logical first = TRUE; /*************************************************************************** * First time... ***************************************************************************/ if (first) { EncodeKeyDefinitions (1, trailerBrowse, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NEXTVARkey_EDIT); EncodeKeyDefinitions (3, trailerEdit, ENTERkey_FSI, CREATEATTRkey_EDIT, NEXTVARkey_EDIT, EXITkey_FSI, CREATEENTRYkey_EDIT, DELETEATTRorENTRYkey_EDIT, HELPkey_FSI); first = FALSE; } if (browseOnly) { IW.NiRows = 14; IW.NtLines = 1; IW.tLines = trailerBrowse; IW.exitChars = exitCharsBrowse; } else { IW.NiRows = 12; IW.NtLines = 3; IW.tLines = trailerEdit; IW.exitChars = exitCharsEdit; } /*************************************************************************** * Build attribute/entry lines and display window. ***************************************************************************/ if (!BuildVarEntryMenu(Z,varN,&nAttrs,&attrNs,&entryIs,&IW)) return FALSE; ItemWindow (NEWiw, &IW, 0); /*************************************************************************** * Read/process keystrokes until request to exit menu. ***************************************************************************/ for (;;) { ItemWindow (READiw, &IW); switch (IW.key) { /*********************************************************************** * Item selected. ***********************************************************************/ case ENTERkey_FSI: { int fieldN, nameItemN; /********************************************************************* * Do any items exist? *********************************************************************/ if (IW.nItems == 0) { ProblemWindow ("Nothing selected (no vAttributes exist).", FALSE); break; } /********************************************************************* * Calculate attribute and field numbers. *********************************************************************/ for (attrX = 0, nameItemN = 0; attrX < nAttrs; attrX++) { int nItems = (int) (entryIs[attrX] ? 4 : 1); if (IW.itemN < nameItemN + nItems) { attrN = attrNs[attrX]; fieldN = IW.itemN - nameItemN; break; } nameItemN += nItems; } /********************************************************************* * Perform desired function (based on field number). *********************************************************************/ switch (fieldN) { /******************************************************************* * Modify attribute name. *******************************************************************/ case 0: { char attrName[CDF_ATTR_NAME_LEN256+1]; status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (browseOnly) ShowFullName (attrName, TRUE); else { static char *header[] = { "Enter new name (with delimiters)...", "Syntax: ...", "Example: \"RANGE\"" }; AOSs1 (trailer, "Enter: ________ Exit: ________ Help: ________") static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static char value[1+CDF_ATTR_NAME_LEN256+1+1]; static char label[15+CDF_ATTR_NAME_LEN256+1]; static struct PromptWindowStruct PW = { label, 4, 1, 78, 3, header, CDF_ATTR_NAME_LEN256+2, value, 1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; char delim; EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); delim = PickDelimiter (attrName, strlen(attrName)); sprintf (value, "%c%s%c", delim, attrName, delim); sprintf (label, " vAttribute %c%s%c ", delim, attrName, delim); PromptWindow (NEWpw, &PW, (int) (strlen(PW.value) - 1), LogicalTRUE); for (;;) { if (EnterPW(&PW,ATTRRENAMEhelpID)) { char attrName[CDF_ATTR_NAME_LEN256+1]; if (DecodeDelimitedString(PW.value,attrName)) { status = CDFlib (PUT_, ATTR_NAME_, attrName, NULL_); if (ReportStatus(status,FALSE)) { FreeVarEntryMenu (attrNs, entryIs, &IW); if (!BuildVarEntryMenu(Z,varN,&nAttrs, &attrNs,&entryIs,&IW)) { PromptWindow (DELETEpw, &PW); ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); break; } if (NoMoreAccess(NULL)) { PromptWindow (DELETEpw, &PW); ItemWindow (DELETEiw, &IW); return FALSE; } } else ProblemWindow ("Illegal name (check delimiters).", FALSE); } else break; } PromptWindow (DELETEpw, &PW); } break; } /******************************************************************* * Modify data specification. *******************************************************************/ case 1: { if (browseOnly) ItemWindow (BEEPiw, &IW); else { long dataType, numElems; char varName[CDF_VAR_NAME_LEN256+1], delim; status = CDFlib (SELECT_, VAR(Z), varN, ATTR_, attrN, BOO(Z,zENTRY_,rENTRY_), varN, GET_, VAR_NAME(Z), varName, BOO(Z,zENTRY_DATATYPE_, rENTRY_DATATYPE_), &dataType, BOO(Z,zENTRY_NUMELEMS_, rENTRY_NUMELEMS_), &numElems, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } delim = PickDelimiter (varName, strlen(varName)); sprintf (label, " %cEntry for %c%s%c ", BOO(Z,'z','r'), delim, varName, delim); if (SelectDataSpec(&dataType,NULL,label)) { status = CDFlib (PUT_, BOO(Z,zENTRY_DATASPEC_, rENTRY_DATASPEC_), dataType, numElems, NULL_); if (ReportStatus(status,FALSE)) { FreeVarEntryMenu (attrNs, entryIs, &IW); if (!BuildVarEntryMenu(Z,varN,&nAttrs, &attrNs,&entryIs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); } else { if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } } } break; } /******************************************************************* * Modify data specification/value(s). *******************************************************************/ case 2: { if (browseOnly) ItemWindow (BEEPiw, &IW); else { Logical changed = FALSE; if (!EditEntry(attrN,varN, BOO(Z,zENTRYt,rENTRYt), TRUE,&changed)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (changed) { FreeVarEntryMenu (attrNs, entryIs, &IW); if (!BuildVarEntryMenu(Z,varN,&nAttrs,&attrNs,&entryIs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); } } break; } /******************************************************************* * Modify value(s). *******************************************************************/ case 3: { Logical changed = FALSE; if (!EditEntry(attrN,varN, BOO(Z,zENTRYt,rENTRYt), FALSE,&changed)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (changed) { FreeVarEntryMenu (attrNs, entryIs, &IW); if (!BuildVarEntryMenu(Z,varN,&nAttrs, &attrNs,&entryIs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); } break; } } break; } /*********************************************************************** * Create attribute. ***********************************************************************/ case CREATEATTRkey_EDIT: { static char *header[] = { "Enter name (with delimiters)...", "Syntax: ...", "Example: \"MetricUnits\"" }; AOSs1 (trailer, "Enter: ________ Exit: ________ Help: _______") static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static char value[DELIMed_ATTR_NAME_LEN+1]; static struct PromptWindowStruct PWt = { " New vAttribute ", 4, 1, 78, 3, header, CDF_ATTR_NAME_LEN256+2, value, 1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); strcpyX (PWt.value, "\"\"", DELIMed_ATTR_NAME_LEN); PromptWindow (NEWpw, &PWt, 1, LogicalTRUE); for (;;) { if (EnterPW(&PWt,ATTRNAMEhelpID)) { char attrName[CDF_ATTR_NAME_LEN256+1]; long attrNum; if (DecodeDelimitedString(PWt.value,attrName)) { status = CDFlib (CREATE_, ATTR_, attrName, VARIABLE_SCOPE, &attrNum, NULL_); if (ReportStatus(status,FALSE)) { FreeVarEntryMenu (attrNs, entryIs, &IW); if (!BuildVarEntryMenu(Z,varN,&nAttrs, &attrNs,&entryIs,&IW)) { PromptWindow (DELETEpw, &PWt); ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.nItems - 1); break; } if (NoMoreAccess(NULL)) { PromptWindow (DELETEpw, &PWt); ItemWindow (DELETEiw, &IW); return FALSE; } } else ProblemWindow ("Illegal name (check delimiters).", FALSE); } else break; } PromptWindow (DELETEpw, &PWt); break; } /*********************************************************************** * Create entry. ***********************************************************************/ case CREATEENTRYkey_EDIT: { int nameItemN; /********************************************************************* * Do any items exist? *********************************************************************/ if (IW.nItems == 0) { ProblemWindow ("A vAttribute isn't selected (none exist).", FALSE); break; } /********************************************************************* * Calculate attribute number. *********************************************************************/ for (attrX = 0, nameItemN = 0; attrX < nAttrs; attrX++) { int nItems = (int) (entryIs[attrX] ? 4 : 1); if (IW.itemN < nameItemN + nItems) { attrN = attrNs[attrX]; break; } nameItemN += nItems; } /********************************************************************* * Create entry (unless it already exists). *********************************************************************/ if (entryIs[attrX]) ProblemWindow ("An entry already exists.", FALSE); else { Logical changed = FALSE; if (!EditEntry(attrN,varN,BOO(Z,zENTRYt,rENTRYt),TRUE,&changed)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (changed) { FreeVarEntryMenu (attrNs, entryIs, &IW); if (!BuildVarEntryMenu(Z,varN,&nAttrs,&attrNs,&entryIs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, nameItemN); } } break; } /*********************************************************************** * Delete entry. ***********************************************************************/ case DELETEATTRorENTRYkey_EDIT: { int nameItemN; /********************************************************************* * Do any items exist? *********************************************************************/ if (IW.nItems == 0) { ProblemWindow ("A vAttribute isn't selected (none exist).", FALSE); break; } /********************************************************************* * Calculate attribute number. *********************************************************************/ for (attrX = 0, nameItemN = 0; attrX < nAttrs; attrX++) { int nItems = (int) (entryIs[attrX] ? 4 : 1); if (IW.itemN < nameItemN + nItems) { attrN = attrNs[attrX]; break; } nameItemN += nItems; } /********************************************************************* * Delete entry (unless it doesn't exist). *********************************************************************/ if (entryIs[attrX]) { char attrName[CDF_ATTR_NAME_LEN256+1], varName[CDF_VAR_NAME_LEN256+1], question1[28+1+CDF_ATTR_NAME_LEN256+1+1], question2[29+1+CDF_VAR_NAME_LEN256+1+1], delim; status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, SELECT_, BOO(Z,zVAR_,rVAR_), varN, GET_, BOO(Z,zVAR_NAME_,rVAR_NAME_), varName, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } delim = PickDelimiter (attrName, strlen(attrName)); sprintf (question1, "Delete %sEntry of vAttribute %c%s%c", BOO(Z,"z","r"), delim, attrName, delim); delim = PickDelimiter (varName, strlen(varName)); sprintf (question2, "corresponding to %sVariable %c%s%c ?", BOO(Z,"z","r"), delim, varName, delim); if (ConfirmWindow(4,78,question1,question2, FALSE,DELETEENTRYhelpID)) { status = CDFlib (SELECT_, BOO(Z,zENTRY_,rENTRY_), varN, DELETE_, BOO(Z,zENTRY_,rENTRY_), NULL_); if (ReportStatus(status,FALSE)) { FreeVarEntryMenu (attrNs, entryIs, &IW); if (!BuildVarEntryMenu(Z,varN,&nAttrs, &attrNs,&entryIs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, nameItemN); } else { if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } } } else ProblemWindow ("An entry does not exist.", FALSE); break; } /*********************************************************************** * Next variable. ***********************************************************************/ case NEXTVARkey_EDIT: varN = (varN + 1) % nVars; FreeVarEntryMenu (attrNs, entryIs, &IW); if (!BuildVarEntryMenu(Z,varN,&nAttrs,&attrNs,&entryIs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, 0); break; /*********************************************************************** * Display online help. ***********************************************************************/ case HELPkey_FSI: OnlineHelpWindow (ilhFile, ENTRIEShelpID); break; /*********************************************************************** * Exit menu. ***********************************************************************/ case EXITkey_FSI: ItemWindow (DELETEiw, &IW); FreeVarEntryMenu (attrNs, entryIs, &IW); return TRUE; } } } /****************************************************************************** * BuildVarEntryMenu. ******************************************************************************/ Logical BuildVarEntryMenu (Z, varN, nAttrs, attrNs, entryIs, IW) Logical Z; long varN; long *nAttrs; long **attrNs; Logical **entryIs; struct ItemWindowStruct *IW; { CDFstatus status; int attrX, curItem, curCol, lineN, n, nItems, dataSpecCol; long dataType, numElems, attrN; char attrName[CDF_ATTR_NAME_LEN256+1], varName[CDF_VAR_NAME_LEN256+1], delim, field[80+1]; void *binary; /*************************************************************************** * Determine number of attributes (of variable scope). ***************************************************************************/ status = CDFlib (GET_, CDF_NUMvATTRS_, nAttrs, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /*************************************************************************** * Count/save attribute numbers. ***************************************************************************/ *attrNs = (long *) cdf_AllocateMemory ((size_t) (*nAttrs * sizeof(long)), FatalError); *entryIs = (Logical *) cdf_AllocateMemory ((size_t) (*nAttrs * sizeof(Logical)), FatalError); for (attrN = 0, attrX = 0, nItems = 0; attrX < *nAttrs; attrN++) { long scope; /************************************************************************ * Determine scope. ************************************************************************/ status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_SCOPE_, &scope, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /************************************************************************ * If proper scope, save attribute number and determine if entry exists. ************************************************************************/ if (scope == VARIABLE_SCOPE) { (*attrNs)[attrX] = attrN; status = CDFlib (SELECT_, BOO(Z,zENTRY_,rENTRY_), varN, GET_, BOO(Z,zENTRY_DATATYPE_, rENTRY_DATATYPE_), &dataType, NULL_); switch (status) { case NO_SUCH_ENTRY: (*entryIs)[attrX] = FALSE; nItems += 1; break; default: if (!ReportStatus(status,FALSE)) return FALSE; (*entryIs)[attrX] = TRUE; nItems += 4; break; } attrX++; } } /*************************************************************************** * Allocate item section control/lines. ***************************************************************************/ AllocIW (IW, nItems, (int) *nAttrs, 80, FatalError); /*************************************************************************** * Encode label/header. ***************************************************************************/ status = CDFlib (SELECT_, VAR(Z), varN, GET_, VAR_NAME(Z), varName, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; delim = PickDelimiter (varName, strlen(varName)); sprintf (IW->label, " %cVariable %c%s%c %cEntries ", BOO(Z,'z','r'), delim, varName, delim, BOO(Z,'z','r')); sprintf (IW->hLines[0],"%ld vAttributes", *nAttrs); strcpyX (IW->hLines[1], "AttrName DataSpec Value(s)", 0); /*************************************************************************** * Build each attribute/entry line. ***************************************************************************/ lineN = 0; curItem = 0; for (attrX = 0; attrX < *nAttrs; attrX++) { /************************************************************************ * Inquire attribute/entry. ************************************************************************/ status = CDFlib (SELECT_, ATTR_, (*attrNs)[attrX], GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /************************************************************************ * Setup attribute name. ************************************************************************/ curCol = 0; EncodeString (strlen(attrName), attrName, field, 0, ATTRNAME_FIELD_LEN); strcpyX (IW->iLines[lineN], field, 0); if (strlen(field) < (size_t) ATTRNAME_FIELD_LEN) { CatNcharacters (IW->iLines[lineN], ATTRNAME_FIELD_LEN - strlen(field), (int) ' '); } CatNcharacters (IW->iLines[lineN], ATTRNAME_FIELD_BLANKS, (int) ' '); IW->iLineNs[curItem] = lineN; IW->iCols[curItem] = curCol; IW->iLens[curItem] = strlen(field); curCol += ATTRNAME_FIELD_LEN + ATTRNAME_FIELD_BLANKS; curItem++; /************************************************************************ * Setup entry data specification/value(s). ************************************************************************/ if ((*entryIs)[attrX]) { status = CDFlib (SELECT_, BOO(Z,zENTRY_,rENTRY_), varN, GET_, BOO(Z,zENTRY_DATATYPE_, rENTRY_DATATYPE_), &dataType, BOO(Z,zENTRY_NUMELEMS_, rENTRY_NUMELEMS_), &numElems, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; strcpyX (field, DataTypeToken(dataType), 0); catchrX (field, (int) '/', 0); sprintf (&field[strlen(field)], "%ld", numElems); if (strlen(field) > (size_t) DATASPEC_FIELD_LEN) { strcpyX (field + DATASPEC_FIELD_LEN - 3, "...", 0); } strcatX (IW->iLines[lineN], field, 0); if (strlen(field) < (size_t) DATASPEC_FIELD_LEN) { CatNcharacters (IW->iLines[lineN], DATASPEC_FIELD_LEN - strlen(field), (int) ' '); } CatNcharacters (IW->iLines[lineN], DATASPEC_FIELD_BLANKS, (int) ' '); IW->iLineNs[curItem] = lineN; IW->iCols[curItem] = curCol; IW->iLens[curItem] = strlen(field); dataSpecCol = curCol; curCol += DATASPEC_FIELD_LEN + DATASPEC_FIELD_BLANKS; curItem++; binary = cdf_AllocateMemory ((size_t) (numElems * CDFelemSize(dataType)), FatalError); status = CDFlib (GET_, BOO(Z,zENTRY_DATA_,rENTRY_DATA_), binary, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; n = EncodeValuesFormat (dataType, numElems, binary, &(IW->iLines[lineN][curCol]), NULL, 0, varENTRYVALUE_FIELD_LEN, EPOCH0_STYLE); cdf_FreeMemory (binary, FatalError); IW->iLineNs[curItem] = lineN; IW->iCols[curItem] = dataSpecCol; IW->iLens[curItem] = strlen(&(IW->iLines[lineN][dataSpecCol])); curItem++; IW->iLineNs[curItem] = lineN; IW->iCols[curItem] = curCol; IW->iLens[curItem] = n; curItem++; } lineN++; } return TRUE; } /****************************************************************************** * FreeVarEntryMenu. ******************************************************************************/ void FreeVarEntryMenu (attrNs, entryIs, IW) long *attrNs; Logical *entryIs; struct ItemWindowStruct *IW; { FreeIW (IW, FatalError); if (attrNs != NULL) cdf_FreeMemory (attrNs, FatalError); if (entryIs != NULL) cdf_FreeMemory (entryIs, FatalError); return; } /****************************************************************************** * CreateEntry. ******************************************************************************/ Logical CreateEntry (G, attrN, changed) Logical G; long attrN; Logical *changed; /* Assumed to be initialized to FALSE by caller. */ { long entryN; int entryType; char attrName[CDF_ATTR_NAME_LEN256+1], delim; CDFstatus status; /**************************************************************************** * Inquire attribute name and delimiter to be used. ****************************************************************************/ status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; delim = PickDelimiter (attrName, strlen(attrName)); if (G) { /************************************************************************** * Global scope attribute, prompt for entry number. **************************************************************************/ static char *header[] = { "Enter gEntry number..." }; AOSs2 (trailer, "Enter: ________ Exit: ________", "Help: ________") static char value[MAX_ENTRYNUM_LEN+1]; static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static char label[15+CDF_ATTR_NAME_LEN256+1]; static struct PromptWindowStruct PW = { label, 4, 23, 34, 1, header, MAX_ENTRYNUM_LEN, value, 2, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; entryType = gENTRYt; EncodeKeyDefinitions (2, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); strcpyX (PW.value, "", MAX_ENTRYNUM_LEN); sprintf (label, " gAttribute %c%s%c ", delim, attrName, delim); PromptWindow (NEWpw, &PW, 0, LogicalTRUE); for (;;) { if (EnterPW(&PW,ENTRYNUMBERhelpID)) { long entryNt; Logical exists; if (sscanf(PW.value,"%ld",&entryNt) == 1) { if (entryNt > 0) { if (!EntryExists(attrN,entryNt-1,entryType,&exists)) { PromptWindow (DELETEpw, &PW); return FALSE; } if (!exists) { entryN = entryNt - 1; break; } else ProblemWindow (E3(entryType,"That gEntry already exists.", "That rEntry already exists.", "That zEntry already exists."), FALSE); } else ProblemWindow ("Illegal gEntry number.", FALSE); } else ProblemWindow ("Error decoding gEntry number.", FALSE); } else { entryN = -1; break; } } PromptWindow (DELETEpw, &PW); } else { /************************************************************************** * Variable scope attribute, select corresponding variable (or enter entry * number). **************************************************************************/ static char *header[] = { "Select the corresponding variable..." }; AOSs3 (trailer, "Select: ________ Numbered rEntry: ________", "Exit: ________ Numbered zEntry: ________", "Help: ________") static int exitChars[] = { ENTERkey_FSI, rENTRYbyNUMBERkey_EDIT, EXITkey_FSI, zENTRYbyNUMBERkey_EDIT, HELPkey_FSI, NUL }; static char label[15+CDF_ATTR_NAME_LEN256+1]; static struct ItemWindowStruct IW = { 4, 16, 48, label, 1, header, 0, NULL, 0, NULL, NULL, NULL, 7, 3, trailer, exitChars, REFRESHkey_FSI, TRUE, NSkey_FSI, PSkey_FSI }; CDFstatus status; long NrVars, NzVars; int nVars, varX; EncodeKeyDefinitions (3, trailer, ENTERkey_FSI, rENTRYbyNUMBERkey_EDIT, EXITkey_FSI, zENTRYbyNUMBERkey_EDIT, HELPkey_FSI); sprintf (label, " vAttribute %c%s%c ", delim, attrName, delim); status = CDFlib (GET_, CDF_NUMrVARS_, &NrVars, CDF_NUMzVARS_, &NzVars, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; nVars = (int) (NrVars + NzVars); AllocIW (&IW, nVars, nVars, 1+CDF_VAR_NAME_LEN256+1+1, FatalError); for (varX = 0; varX < nVars; varX++) { char varName[CDF_VAR_NAME_LEN256+1], delim; size_t lengthX; Logical Z = (varX < NrVars ? FALSE : TRUE); long varN = BOO(Z,varX-NrVars,varX); status = CDFlib (SELECT_, VAR(Z), varN, GET_, VAR_NAME(Z), varName, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; delim = PickDelimiter (varName, strlen(varName)); sprintf (IW.iLines[varX], "%c%s%c", delim, varName, delim); IW.iLineNs[varX] = varX; IW.iCols[varX] = 0; lengthX = strlen(IW.iLines[varX]); IW.iLens[varX] = (int) MINIMUM(40,lengthX); } ItemWindow (NEWiw, &IW, 0); for (entryN = -2; entryN == -2; ) { ItemWindow (READiw, &IW); switch (IW.key) { case ENTERkey_FSI: if (IW.nItems == 0) ProblemWindow ("No variables exist.", FALSE); else { Logical Z = BOO(IW.itemN < NrVars,FALSE,TRUE), exists; long entryNt = BOO(Z,IW.itemN-NrVars,IW.itemN); entryType = BOO(Z,zENTRYt,rENTRYt); if (!EntryExists(attrN,entryNt,entryType,&exists)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (!exists) entryN = entryNt; else ProblemWindow (E3(entryType,"That gEntry already exists.", "That rEntry already exists.", "That zEntry already exists."), FALSE); } break; case zENTRYbyNUMBERkey_EDIT: case rENTRYbyNUMBERkey_EDIT: { static char *rHeader[] = { "Enter rEntry number..." }; static char *zHeader[] = { "Enter zEntry number..." }; AOSs2 (trailer, "Enter: ________ Exit: ________", "Help: ________") static char value[MAX_ENTRYNUM_LEN+1]; static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static char label[15+CDF_ATTR_NAME_LEN256+1]; static struct PromptWindowStruct PW = { label, 7, 23, 34, 1, NULL, MAX_ENTRYNUM_LEN, value, 2, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; Logical Z = (IW.key == zENTRYbyNUMBERkey_EDIT); entryType = BOO(Z,zENTRYt,rENTRYt); EncodeKeyDefinitions (2, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); PW.hLines = BOO(Z,zHeader,rHeader); strcpyX (PW.value, "", MAX_ENTRYNUM_LEN); sprintf (label, " vAttribute %c%s%c ", delim, attrName, delim); PromptWindow (NEWpw, &PW, 0, LogicalTRUE); for (;;) { if (EnterPW(&PW,ENTRYNUMBERhelpID)) { long entryNt; Logical exists; if (sscanf(PW.value,"%ld",&entryNt) == 1) { if (entryNt > 0) { if (!EntryExists(attrN,entryNt-1,entryType,&exists)) { PromptWindow (DELETEpw, &PW); return FALSE; } if (!exists) { entryN = entryNt - 1; break; } else ProblemWindow (E3(entryType, "That gEntry already exists.", "That rEntry already exists.", "That zEntry already exists."), FALSE); } else ProblemWindow (BOO(Z,"Illegal zEntry number.", "Illegal rEntry number."), FALSE); } else ProblemWindow (BOO(Z,"Error decoding zEntry number.", "Error decoding rEntry number."),FALSE); } else { entryN = -1; break; } } PromptWindow (DELETEpw, &PW); break; } case HELPkey_FSI: OnlineHelpWindow (ilhFile, VARSELECThelpID); break; case EXITkey_FSI: entryN = -1; break; } } ItemWindow (DELETEiw, &IW); FreeIW (&IW, FatalError); } /**************************************************************************** * Return if an entry number wasn't selected/entered. ****************************************************************************/ if (entryN == -1) return TRUE; /**************************************************************************** * Create the entry. ****************************************************************************/ return EditEntry(attrN,entryN,entryType,TRUE,changed); } /****************************************************************************** * EntryExists. ******************************************************************************/ Logical EntryExists (attrN, entryN, entryType, exists) long attrN; long entryN; int entryType; Logical *exists; { CDFstatus status = CDFlib (SELECT_, ATTR_, attrN, CONFIRM_, ENTRY_EXISTENCE(entryType), entryN, NULL_); switch (status) { case NO_SUCH_ENTRY: *exists = FALSE; break; default: ReportStatus (status, FALSE); if (StatusBAD(status)) return FALSE; *exists = StatusOK(status); break; } return TRUE; } /****************************************************************************** * EditAttrsX. ******************************************************************************/ Logical EditAttrsX (G, CDFname) Logical G; /* If TRUE, global scoped attributes. */ char *CDFname; /* Name of the CDF being edited. */ { CDFstatus status; long nAttrs; /* Total number of attributes. */ long nAttrsOfScope; /* Number of attributes of the proper scope. */ long attrN; long fieldN; long *attrNs; AOSs2 (header, BLANKs78, BLANKs78) AOSs1 (trailerBrowse, "Select: ________ Exit: ________ Help: ________") AOSs2A (trailerEdit, "Select: ________ Create attribute: ________ Toggle scope: ________", "Exit: ________ Help: ________ Delete attribute: ________") static int exitCharsBrowse[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static int exitCharsEdit[] = { ENTERkey_FSI, EXITkey_FSI, CREATEATTRkey_EDIT, HELPkey_FSI, TOGGLESCOPEkey_EDIT, DELETEATTRorENTRYkey_EDIT, NUL }; static char label[6+DU_MAX_NAME_LEN+14+1]; static struct ItemWindowStruct IW = { 0, 0, 80, label, 2, header, 0, NULL, 0, NULL, NULL, NULL, 0, 0, NULL, NULL, REFRESHkey_FSI, TRUE, NSkey_FSI, PSkey_FSI }; static Logical first = TRUE; /*************************************************************************** * First time... ***************************************************************************/ if (first) { EncodeKeyDefinitions (1, trailerBrowse, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); EncodeKeyDefinitions (2, trailerEdit, ENTERkey_FSI, CREATEATTRkey_EDIT, TOGGLESCOPEkey_EDIT, EXITkey_FSI, HELPkey_FSI, DELETEATTRorENTRYkey_EDIT); first = FALSE; } if (browseOnly) { IW.NiRows = 14; IW.NtLines = 1; IW.tLines = trailerBrowse; IW.exitChars = exitCharsBrowse; } else { IW.NiRows = 13; IW.NtLines = 2; IW.tLines = trailerEdit; IW.exitChars = exitCharsEdit; } /*************************************************************************** * Build attribute lines and display menu. ***************************************************************************/ if (!BuildAttrMenuX(G,CDFname,&nAttrs, &nAttrsOfScope,&attrNs,&IW)) return FALSE; ItemWindow (NEWiw, &IW, 0); /*************************************************************************** * Read/process keystrokes until request to exit menu. ***************************************************************************/ for (;;) { ItemWindow (READiw, &IW); if (IW.nItems != 0) { fieldN = IW.itemN % 3; attrN = attrNs[IW.itemN/3]; } switch (IW.key) { /*********************************************************************** * Item selected. ***********************************************************************/ case ENTERkey_FSI: { /********************************************************************* * Check if any attributes/entries exist. *********************************************************************/ if (IW.nItems == 0) { ProblemWindow (BOO(G,"Nothing selected (no gAttributes exist).", "Nothing selected (no vAttributes exist)."), FALSE); break; } /********************************************************************* * Perform desired function (based on field number). *********************************************************************/ switch (fieldN) { /******************************************************************* * Modify attribute name. *******************************************************************/ case 0: { char attrName[CDF_ATTR_NAME_LEN256+1]; status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (browseOnly) { ShowFullName (attrName, TRUE); } else { static char *header[] = { "Enter new name (with delimiters)...", "Syntax: ...", "Example: \"FILTERs\"" }; AOSs1 (trailer, "Enter: ________ Exit: ________ Help: ________") static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static char value[1+CDF_ATTR_NAME_LEN256+1+1]; static char label[15+CDF_ATTR_NAME_LEN256+1]; static struct PromptWindowStruct PWt = { label, 4, 1, 78, 3, header, CDF_ATTR_NAME_LEN256+2, value, 1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; char delim; EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); delim = PickDelimiter (attrName, strlen(attrName)); sprintf (value, "%c%s%c", delim, attrName, delim); sprintf (label, " %cAttribute %c%s%c ", BOO(G,'g','v'), delim, attrName, delim); PromptWindow (NEWpw, &PWt, (int)(strlen(PWt.value) - 1), LogicalTRUE); for (;;) { if (EnterPW(&PWt,ATTRRENAMEhelpID)) { char attrName[CDF_ATTR_NAME_LEN256+1]; if (DecodeDelimitedString(PWt.value,attrName)) { status = CDFlib (PUT_, ATTR_NAME_, attrName, NULL_); if (ReportStatus(status,FALSE)) { FreeAttrMenuX (attrNs, &IW); if (!BuildAttrMenuX(G,CDFname,&nAttrs, &nAttrsOfScope,&attrNs,&IW)) { PromptWindow (DELETEpw, &PWt); ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); break; } if (NoMoreAccess(NULL)) { PromptWindow (DELETEpw, &PWt); ItemWindow (DELETEiw, &IW); return FALSE; } } else ProblemWindow ("Illegal name (check delimiters).", FALSE); } else break; } PromptWindow (DELETEpw, &PWt); } break; } /******************************************************************* * Edit entries. *******************************************************************/ case 1: { ItemWindow (UNDISPLAYiw, &IW); if (!EditAttrEntriesX(G,attrN,nAttrs)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (REDISPLAYiw, &IW); break; } /******************************************************************* * TextEdit entries. *******************************************************************/ case 2: { if (G) { if (!TextEditEntries(attrN)) { ItemWindow (DELETEiw, &IW); return FALSE; } } else ProblemWindow ("Not supported for vAttributes.", FALSE); break; } } break; } /*********************************************************************** * Create new attribute. ***********************************************************************/ case CREATEATTRkey_EDIT: { static char *header[] = { "Enter name (with delimiters)...", "Syntax: ...", "Example: \"Resolution\"" }; AOSs1 (trailer, "Enter: ________ Exit: ________ Help: ________") static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static char value[DELIMed_ATTR_NAME_LEN+1]; static char label[16+1]; static struct PromptWindowStruct PWt = { label, 4, 1, 78, 3, header, CDF_ATTR_NAME_LEN256+2, value, 1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); strcpyX (value, "\"\"", DELIMed_ATTR_NAME_LEN); sprintf (label, " New %cAttribute ", BOO(G,'g','v')); PromptWindow (NEWpw, &PWt, 1, LogicalTRUE); for (;;) { if (EnterPW(&PWt,ATTRNAMEhelpID)) { char attrName[CDF_ATTR_NAME_LEN256+1]; long attrNum; if (DecodeDelimitedString(PWt.value,attrName)) { status = CDFlib (CREATE_, ATTR_, attrName, BOO(G,GLOBAL_SCOPE, VARIABLE_SCOPE), &attrNum, NULL_); if (ReportStatus(status,FALSE)) { FreeAttrMenuX (attrNs, &IW); if (!BuildAttrMenuX(G,CDFname,&nAttrs, &nAttrsOfScope,&attrNs,&IW)) { PromptWindow (DELETEpw, &PWt); ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.nItems - 3); break; } if (NoMoreAccess(NULL)) { PromptWindow (DELETEpw, &PWt); ItemWindow (DELETEiw, &IW); return FALSE; } } else ProblemWindow ("Illegal name (check delimiters).", FALSE); } else break; } PromptWindow (DELETEpw, &PWt); break; } /*********************************************************************** * Delete attribute. ***********************************************************************/ case DELETEATTRorENTRYkey_EDIT: { char attrName[CDF_ATTR_NAME_LEN256+1], question[22+CDF_ATTR_NAME_LEN256+1], delim; if (IW.nItems == 0) { ProblemWindow (BOO(G,"A gAttribute isn't selected (none exist).", "A vAttribute isn't selected (none exist)."), FALSE); break; } status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } delim = PickDelimiter (attrName, strlen(attrName)); sprintf (question, "Delete %sAttribute %c%s%c ?", BOO(G,"g","v"), delim, attrName, delim); if (ConfirmWindow(4,78,question,NULL,FALSE,DELETEATTRhelpID)) { status = CDFlib (DELETE_, ATTR_, NULL_); if (ReportStatus(status,FALSE)) { int itemNt = IW.itemN - (IW.itemN % 3); FreeAttrMenuX (attrNs, &IW); if (!BuildAttrMenuX(G,CDFname,&nAttrs, &nAttrsOfScope,&attrNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (itemNt == IW.nItems) itemNt = MaxInt (0, itemNt - 3); ItemWindow (UPDATEiw, &IW, itemNt); } else { if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } } break; } /*********************************************************************** * Toggle scope. ***********************************************************************/ case TOGGLESCOPEkey_EDIT: { if (IW.nItems == 0) { ProblemWindow(BOO(G,"A gAttribute isn't selected (none exist).", "A vAttribute isn't selected (none exist)."), FALSE); break; } status = CDFlib (SELECT_,ATTR_,attrN, PUT_,ATTR_SCOPE_,BOO(G,VARIABLE_SCOPE,GLOBAL_SCOPE), NULL_); if (ReportStatus(status,FALSE)) { int itemNt = IW.itemN - (IW.itemN % 3); FreeAttrMenuX (attrNs, &IW); if (!BuildAttrMenuX(G,CDFname,&nAttrs, &nAttrsOfScope,&attrNs,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (itemNt == IW.nItems) itemNt = MaxInt (0, itemNt - 3); ItemWindow (UPDATEiw, &IW, itemNt); } else { if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } break; } /*********************************************************************** * Display online help. ***********************************************************************/ case HELPkey_FSI: OnlineHelpWindow (ilhFile, BOO(G,GATTRShelpIDx,VATTRShelpIDx)); break; /*********************************************************************** * Exit menu. ***********************************************************************/ case EXITkey_FSI: ItemWindow (DELETEiw, &IW); FreeAttrMenuX (attrNs, &IW); return TRUE; } } } /****************************************************************************** * BuildAttrMenuX. ******************************************************************************/ Logical BuildAttrMenuX (G, CDFname, nAttrs, nAttrsOfScope, attrNs, IW) Logical G; char *CDFname; long *nAttrs; long *nAttrsOfScope; long **attrNs; struct ItemWindowStruct *IW; { CDFstatus status; long attrN; int lineN; size_t nBytes; int attrNameFieldLen = BOO(browseOnly,ATTRNAME_bFIELD_LEN, ATTRNAME_eFIELD_LEN); /*************************************************************************** * Determine number of attributes (total and of proper scope). ***************************************************************************/ status = CDFlib (GET_, CDF_NUMATTRS_, nAttrs, BOO(G,CDF_NUMgATTRS_,CDF_NUMvATTRS_), nAttrsOfScope, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /*************************************************************************** * Allocate item section control/lines. ***************************************************************************/ nBytes = (size_t) (*nAttrsOfScope * sizeof(long)); *attrNs = (long *) cdf_AllocateMemory (nBytes, FatalError); AllocIW (IW, (int) (3 * (*nAttrsOfScope)), (int) *nAttrsOfScope, 80, FatalError); /*************************************************************************** * Encode label/header. ***************************************************************************/ sprintf (IW->label, " CDF \"%s\" %cAttributes ", CDFname, BOO(G,'g','v')); if (G) sprintf (IW->hLines[0], "%ld gAttribute%s", *nAttrsOfScope, (*nAttrs == 1 ? "" : "s")); else sprintf (IW->hLines[0], "%ld vAttribute%s", *nAttrsOfScope, (*nAttrs == 1 ? "" : "s")); strcpyX (IW->hLines[1], "AttrName", 0); /*************************************************************************** * Build each attribute/entry line. ***************************************************************************/ for (attrN = 0, lineN = 0; attrN < *nAttrs; attrN++) { long scope; int itemN, nameLen; char attrName[CDF_ATTR_NAME_LEN256+1]; /************************************************************************ * Inquire attribute. ************************************************************************/ status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, ATTR_SCOPE_, &scope, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /************************************************************************ * If of the proper scope... ************************************************************************/ if ((G && scope == GLOBAL_SCOPE) || (!G && scope == VARIABLE_SCOPE)) { /********************************************************************** * Save attribute number. **********************************************************************/ (*attrNs)[lineN] = attrN; /********************************************************************** * Setup attribute name. **********************************************************************/ nameLen = (int) strlen(attrName); EncodeString ((long) nameLen, attrName, IW->iLines[lineN], -attrNameFieldLen, attrNameFieldLen); strcatX (IW->iLines[lineN], " ", 0); itemN = 3 * lineN; IW->iLineNs[itemN] = lineN; IW->iCols[itemN] = 0; IW->iLens[itemN] = MinInt(1 + nameLen + 1,attrNameFieldLen); /********************************************************************** * Setup field. **********************************************************************/ IW->iCols[itemN+1] = (int) strlen(IW->iLines[lineN]); strcatX (IW->iLines[lineN], BOO(browseOnly," "," "), 0); IW->iLineNs[itemN+1] = lineN; IW->iLens[itemN+1] = BOO(browseOnly,16,14); /********************************************************************** * Setup field. **********************************************************************/ IW->iCols[itemN+2] = (int) strlen(IW->iLines[lineN]); strcatX (IW->iLines[lineN], BOO(browseOnly,"",""), 0); IW->iLineNs[itemN+2] = lineN; IW->iLens[itemN+2] = BOO(browseOnly,20,18); /********************************************************************** * Increment to next line. **********************************************************************/ lineN++; } } return TRUE; } /****************************************************************************** * FreeAttrMenuX. ******************************************************************************/ void FreeAttrMenuX (attrNs, IW) long *attrNs; struct ItemWindowStruct *IW; { if (attrNs != NULL) cdf_FreeMemory (attrNs, FatalError); FreeIW (IW, FatalError); return; } /****************************************************************************** * TextEditEntries. ******************************************************************************/ Logical TextEditEntries (attrN) long attrN; /* Attribute number being edited. */ { AOSs1A (header, "Is your favorite editing key missing? If so, contact CDFsupport.") AOSs1B (trailerBrowse, "Exit: ________ Help: ________") AOSs1C (trailerEdit, "Update: ________ Exit: ________ Help: ________") static int exitCharsBrowse[] = { EXITkey_FSI, HELPkey_FSI, NUL }; static int exitCharsEdit[] = { UPDATEkey_EDIT, EXITkey_FSI, HELPkey_FSI }; static char label[12+1+CDF_ATTR_NAME_LEN256+1+13+1]; static struct EditWindowStruct EW = { label, 0, 0, 80, 1, header, NULL, 15, 1, NULL, TRUE, TRUE, NULL, REFRESHkey_FSI, NUL, NUL, NUL, NUL, NSkey_FSI, PSkey_FSI, NUL, NUL, INSERTorOVERkey_FSI }; static Logical first = TRUE; Logical allCharacter; /*************************************************************************** * First time... ***************************************************************************/ if (first) { EncodeKeyDefinitions (1, trailerBrowse, EXITkey_FSI, HELPkey_FSI); EncodeKeyDefinitions (1, trailerEdit, UPDATEkey_EDIT, EXITkey_FSI, HELPkey_FSI); first = FALSE; } if (browseOnly) { EW.tLines = trailerBrowse; EW.exitChars = exitCharsBrowse; EW.readOnly = TRUE; } else { EW.tLines = trailerEdit; EW.exitChars = exitCharsEdit; EW.readOnly = FALSE; } /*************************************************************************** * Build attribute/entry lines and display menu. ***************************************************************************/ if (!BuildTextEditEntriesMenu(attrN,&EW,&allCharacter)) return FALSE; if (!allCharacter) { ProblemWindow ("Not all entries have a character data type.", FALSE); return TRUE; } EditWindow (NEWiw, &EW, TRUE); /*************************************************************************** * Read/process keystrokes until request to exit menu. ***************************************************************************/ for (;;) { EditWindow (READew, &EW); switch (EW.key) { case UPDATEkey_EDIT: { UpdateTextEditEntries (attrN, &EW); EditWindow (DELETEew, &EW); cdf_FreeMemory (EW.eText, FatalError); return (!NoMoreAccess(NULL)); } /*********************************************************************** * Display online help. ***********************************************************************/ case HELPkey_FSI: OnlineHelpWindow (ilhFile, TEXTENTRIEShelpID); break; /*********************************************************************** * Exit menu. ***********************************************************************/ case EXITkey_FSI: EditWindow (DELETEew, &EW); cdf_FreeMemory (EW.eText, FatalError); return TRUE; } } } /****************************************************************************** * BuildTextEditEntriesMenu. * Returns FALSE if a fatal error detected. ******************************************************************************/ Logical BuildTextEditEntriesMenu (attrN, EW, allCharacter) long attrN; /* gAttribute number. */ struct EditWindowStruct *EW; /* EditWindow structure pointer. */ Logical *allCharacter; /* All character data type entries? */ { CDFstatus status; char *line, attrName[CDF_ATTR_NAME_LEN256+1]; int i; long totalChars = 0, maxEntry, entryN, dataType, numElems, totalBytes; /**************************************************************************** * Encode label. ****************************************************************************/ status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; sprintf (EW->label, " gAttribute \"%s\" TextEntries ", attrName); /**************************************************************************** * Verify that all entries have a character data type and count the total * number of characters. ****************************************************************************/ status = CDFlib (GET_, ATTR_MAXgENTRY_, &maxEntry, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; for (entryN = 0; entryN <= maxEntry; entryN++) { status = CDFlib (SELECT_, gENTRY_, entryN, GET_, gENTRY_DATATYPE_, &dataType, gENTRY_NUMELEMS_, &numElems, NULL_); switch (status) { case NO_SUCH_ENTRY: break; default: if (!ReportStatus(status,FALSE)) return FALSE; if (!STRINGdataType(dataType)) { *allCharacter = FALSE; return TRUE; } totalChars += numElems; break; } } /**************************************************************************** * Build text. ****************************************************************************/ totalBytes = (maxEntry + 1) + totalChars + 1; EW->eText = (char *) cdf_AllocateMemory ((size_t) totalBytes, FatalError); MakeNUL (EW->eText); for (entryN = 0; entryN <= maxEntry; entryN++) { status = CDFlib (SELECT_, gENTRY_, entryN, GET_, gENTRY_NUMELEMS_, &numElems, NULL_); switch (status) { case NO_SUCH_ENTRY: strcatX (EW->eText, "\n", (size_t) totalBytes); break; default: if (!ReportStatus(status,FALSE)) return FALSE; line = (char *) cdf_AllocateMemory ((size_t) (numElems + 1), FatalError); status = CDFlib (GET_, gENTRY_DATA_, line, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; for (i = 0; i < numElems; i++) { if (!Printable(line[i])) line[i] = '.'; } line[(int)numElems] = NUL; strcatX (EW->eText, line, (size_t) totalBytes); strcatX (EW->eText, "\n", (size_t) totalBytes); cdf_FreeMemory (line, FatalError); break; } } *allCharacter = TRUE; return TRUE; } /****************************************************************************** * UpdateTextEditEntries. ******************************************************************************/ Logical UpdateTextEditEntries (attrN, EW) long attrN; /* gAttribute number. */ struct EditWindowStruct *EW; /* EditWindow structure pointer. */ { CDFstatus status; long entryN, maxEntryN; char *ptr1, *ptr2; size_t length; /**************************************************************************** * Select attribute. ****************************************************************************/ status = CDFlib (SELECT_, ATTR_, attrN, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /**************************************************************************** * Scan text... ****************************************************************************/ entryN = NO_ENTRY; ptr1 = EW->eText; for (;;) { /************************************************************************* * Look for next newline character. *************************************************************************/ ptr2 = strchr (ptr1, Nl); /************************************************************************* * If a newline character wasn't found, check if one or more characters * exist before the terminating NUL. If not, we're done scanning the * text. *************************************************************************/ if (ptr2 == NULL) { length = strlen (ptr1); if (length == 0) break; ptr2 = ptr1 + length; } else length = (size_t) (ptr2 - ptr1); /************************************************************************* * Rewrite or delete the entry depending on the length of this line of * text. *************************************************************************/ entryN++; if (length > 0) { status = CDFlib (SELECT_, gENTRY_, entryN, PUT_, gENTRY_DATA_, CDF_CHAR, (long) length, ptr1, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; } else { status = CDFlib (SELECT_, gENTRY_, entryN, DELETE_, gENTRY_, NULL_); switch (status) { case NO_SUCH_ENTRY: break; default: if (!ReportStatus(status,FALSE)) return FALSE; break; } } /************************************************************************* * If this line of text ended on the NUL, then we're done scanning the * text. Otherwise, continue at the next character. *************************************************************************/ if (*ptr2 == NUL) break; ptr1 = ptr2 + 1; } /**************************************************************************** * Determine maximum gEntry number. ****************************************************************************/ status = CDFlib (GET_, ATTR_MAXgENTRY_, &maxEntryN, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /**************************************************************************** * Delete remaining entries. ****************************************************************************/ entryN++; while (entryN <= maxEntryN) { status = CDFlib (SELECT_, gENTRY_, entryN, DELETE_, gENTRY_, NULL_); switch (status) { case NO_SUCH_ENTRY: break; default: if (!ReportStatus(status,FALSE)) return FALSE; break; } entryN++; } return TRUE; } /****************************************************************************** * EditAttrEntriesX. ******************************************************************************/ Logical EditAttrEntriesX (G, attrN, nAttrs) Logical G; /* If TRUE, global scoped attribute. */ long attrN; /* Attribute number being edited. */ long nAttrs; /* Number of attributes with this scope. */ { CDFstatus status; long entryN, fieldN, scope; AOSs2 (header, BLANKs78, BLANKs78) AOSs1 (trailerBrowse, "Select: ________ Exit: ________ Help: ________ Next attribute: ________") AOSs2A (trailerEdit, "Modify: ________ Create entry: ________ Delete entry: ________", "Exit: ________ Help: ________ Next attribute: ________") static int exitCharsBrowse[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NEXTATTRkey_EDIT, NUL }; static int exitCharsEdit[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, CREATEENTRYkey_EDIT, DELETEATTRorENTRYkey_EDIT, NEXTATTRkey_EDIT, NUL }; static char label[12+1+CDF_ATTR_NAME_LEN256+1+9+1]; static struct ItemWindowStruct IW = { 0, 0, 80, label, 2, header, 0, NULL, 0, NULL, NULL, NULL, 0, 0, NULL, NULL, REFRESHkey_FSI, TRUE, NSkey_FSI, PSkey_FSI }; long nEntries; long *entryNs; int *entryTypes, entryType; static Logical first = TRUE; /*************************************************************************** * First time... ***************************************************************************/ if (first) { EncodeKeyDefinitions (1, trailerBrowse, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NEXTATTRkey_EDIT); EncodeKeyDefinitions (2, trailerEdit, ENTERkey_FSI, CREATEENTRYkey_EDIT, DELETEATTRorENTRYkey_EDIT, EXITkey_FSI, HELPkey_FSI, NEXTATTRkey_EDIT); first = FALSE; } if (browseOnly) { IW.NiRows = 14; IW.NtLines = 1; IW.tLines = trailerBrowse; IW.exitChars = exitCharsBrowse; } else { IW.NiRows = 13; IW.NtLines = 2; IW.tLines = trailerEdit; IW.exitChars = exitCharsEdit; } /*************************************************************************** * Build attribute/entry lines and display menu. ***************************************************************************/ if (!BuildAttrEntriesMenuX(G,attrN,&nEntries, &entryNs,&entryTypes,&IW)) return FALSE; ItemWindow (NEWiw, &IW, 0); /*************************************************************************** * Read/process keystrokes until request to exit menu. ***************************************************************************/ for (;;) { ItemWindow (READiw, &IW); /********************************************************************* * Calculate entry and field numbers and entry type. *********************************************************************/ if (IW.nItems != 0) { fieldN = IW.itemN % 4; entryN = entryNs[IW.itemN/4]; entryType = entryTypes[IW.itemN/4]; } switch (IW.key) { /*********************************************************************** * Item selected. ***********************************************************************/ case ENTERkey_FSI: { /********************************************************************* * Check if any attributes/entries exist. *********************************************************************/ if (IW.nItems == 0) { ProblemWindow (BOO(G,"Nothing selected (no gEntries exist).", "Nothing selected (no entries exist)."),FALSE); break; } /********************************************************************* * Perform desired function (based on field number). *********************************************************************/ switch (fieldN) { /******************************************************************* * Modify variable name/global entry number. *******************************************************************/ case 0: { if (G) ItemWindow (BEEPiw, &IW); else { char varName[CDF_VAR_NAME_LEN256+1]; long nVars; Logical Z = (entryType == zENTRYt); status = CDFlib (GET_, BOO(Z,CDF_NUMzVARS_, CDF_NUMrVARS_), &nVars, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (entryN >= nVars) { ProblemWindow (BOO(Z,"No corresponding zVariable.", "No corresponding rVariable."), FALSE); break; } status = CDFlib (SELECT_, VAR(Z), entryN, GET_, VAR_NAME(Z), varName, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (browseOnly) ShowFullName (varName, FALSE); else { static char *header[] = { "Enter new name (with delimiters)...", "Syntax: ...", "Example: \"Humidity\"" }; AOSs1 (trailer, "Enter: ________ Exit: ________ Help: ________") static int exitChars[] = { ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI, NUL }; static char value[1+CDF_VAR_NAME_LEN256+1+1]; static char label[14+CDF_VAR_NAME_LEN256+1]; static struct PromptWindowStruct PWt = { label, 4, 1, 78, 3, header, CDF_VAR_NAME_LEN256+2, value, 1, trailer, exitChars, REFRESHkey_FSI, SOLkey_FSI, EOLkey_FSI, INSERTorOVERkey_FSI }; char delim; EncodeKeyDefinitions (1, trailer, ENTERkey_FSI, EXITkey_FSI, HELPkey_FSI); delim = PickDelimiter (varName, strlen(varName)); sprintf (value, "%c%s%c", delim, varName, delim); sprintf (label, " %cVariable %c%s%c ", BOO(Z,'z','r'), delim, varName, delim); PromptWindow (NEWpw, &PWt, (int) (strlen(PWt.value) - 1), LogicalTRUE); for (;;) { if (EnterPW(&PWt,VARRENAMEhelpID)) { char varName[CDF_VAR_NAME_LEN256+1]; if (DecodeDelimitedString(PWt.value,varName)) { status = CDFlib (PUT_, VAR_NAME(Z), varName, NULL_); if (ReportStatus(status,FALSE)) { FreeAttrEntriesMenuX (entryNs, entryTypes, &IW); if (!BuildAttrEntriesMenuX(G,attrN,&nEntries, &entryNs,&entryTypes, &IW)) { PromptWindow (DELETEpw, &PWt); ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); break; } if (NoMoreAccess(NULL)) { PromptWindow (DELETEpw, &PWt); ItemWindow (DELETEiw, &IW); return FALSE; } } else ProblemWindow ("Illegal name (check delimiters).", FALSE); } else break; } PromptWindow (DELETEpw, &PWt); } } break; } /******************************************************************* * Modify data specification. *******************************************************************/ case 1: { if (browseOnly) ItemWindow (BEEPiw, &IW); else { long dataType, numElems; static char label[15+CDF_VAR_NAME_LEN256+1]; if (G) sprintf (label, " gEntry %ld ", entryN + 1); else { Logical Z = (entryType == zENTRYt); char varName[CDF_VAR_NAME_LEN256+1], delim; status = CDFlib (SELECT_, VAR(Z), entryN, GET_, VAR_NAME(Z), varName, NULL_); switch (status) { case NO_SUCH_VAR: sprintf (label," %cEntry %ld ",BOO(Z,'z','r'),entryN + 1); break; default: if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } delim = PickDelimiter (varName, strlen(varName)); sprintf (label, " %cEntry for %c%s%c ", BOO(Z,'z','r'), delim, varName, delim); break; } } status = CDFlib (SELECT_, ATTR_, attrN, ENTRY(entryType), entryN, GET_, ENTRY_DATATYPE(entryType), &dataType, ENTRY_NUMELEMS(entryType), &numElems, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (SelectDataSpec(&dataType,NULL,label)) { status = CDFlib (PUT_, ENTRY_DATASPEC(entryType), dataType, numElems, NULL_); if (ReportStatus(status,FALSE)) { FreeAttrEntriesMenuX (entryNs, entryTypes, &IW); if (!BuildAttrEntriesMenuX(G,attrN,&nEntries,&entryNs, &entryTypes,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); } else { if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } } } break; } /******************************************************************* * Modify data specification/value(s). *******************************************************************/ case 2: { if (browseOnly) ItemWindow (BEEPiw, &IW); else { Logical changed = FALSE; if (!EditEntry(attrN,entryN,entryType,TRUE,&changed)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (changed) { FreeAttrEntriesMenuX (entryNs, entryTypes, &IW); if (!BuildAttrEntriesMenuX(G,attrN,&nEntries, &entryNs,&entryTypes,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); } } break; } /******************************************************************* * Modify value(s). *******************************************************************/ case 3: { Logical changed = FALSE; if (!EditEntry(attrN,entryN,entryType,FALSE,&changed)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (changed) { FreeAttrEntriesMenuX (entryNs, entryTypes, &IW); if (!BuildAttrEntriesMenuX(G,attrN,&nEntries, &entryNs,&entryTypes,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, IW.itemN); } break; } } break; } /*********************************************************************** * Create new entry. ***********************************************************************/ case CREATEENTRYkey_EDIT: { Logical changed = FALSE; if (!CreateEntry(G,attrN,&changed)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (changed) { FreeAttrEntriesMenuX (entryNs, entryTypes, &IW); if (!BuildAttrEntriesMenuX(G,attrN,&nEntries, &entryNs,&entryTypes,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, 0); } break; } /*********************************************************************** * Delete attribute/entry. ***********************************************************************/ case DELETEATTRorENTRYkey_EDIT: { char attrName[CDF_ATTR_NAME_LEN256+1], delim, question1[40+ENTRYNUM_FIELD_LEN+CDF_ATTR_NAME_LEN256+1], question2[31+CDF_VAR_NAME_LEN256+1]; if (IW.nItems == 0) { ProblemWindow (BOO(G,"A gEntry isn't selected (none exist).", "An entry isn't selected (none exist)."), FALSE); break; } status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } delim = PickDelimiter (attrName, strlen(attrName)); if (entryType == gENTRYt) { sprintf (question1, "Delete gEntry number %ld of gAttribute %c%s%c ?", entryN + 1, delim, attrName, delim); question2[0] = NUL; } else { char varName[CDF_VAR_NAME_LEN256+1], attrName[CDF_ATTR_NAME_LEN256+1]; status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, SELECT_, BOO(entryType == zENTRYt,zVAR_, rVAR_), entryN, GET_, BOO(entryType == zENTRYt, zVAR_NAME_,rVAR_NAME_), varName, NULL_); switch (status) { case NO_SUCH_VAR: sprintf (question1, "Delete %sEntry number %ld of vAttribute %c%s%c ?", BOO(entryType==zENTRYt,"z","r"), entryN + 1, delim, attrName, delim); question2[0] = NUL; break; default: if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } delim = PickDelimiter (attrName, strlen(attrName)); sprintf (question1, "Delete %sEntry of vAttribute %c%s%c", BOO(entryType==zENTRYt,"z","r"), delim, attrName, delim); delim = PickDelimiter (varName, strlen(varName)); sprintf (question2, "corresponding to %sVariable %c%s%c ?", BOO(entryType==zENTRYt,"z","r"), delim, varName,delim); break; } } if (ConfirmWindow(4,78,question1, BOO(NULstring(question2),NULL,question2), FALSE,DELETEENTRYhelpID)) { status = CDFlib (SELECT_, ENTRY(entryType), entryN, DELETE_, ENTRY(entryType), NULL_); if (ReportStatus(status,FALSE)) { int itemNt = IW.itemN - (IW.itemN % 4); FreeAttrEntriesMenuX (entryNs, entryTypes, &IW); if (!BuildAttrEntriesMenuX(G,attrN,&nEntries, &entryNs,&entryTypes,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } if (itemNt == IW.nItems) itemNt = MaxInt (0, itemNt - 4); ItemWindow (UPDATEiw, &IW, itemNt); } else { if (NoMoreAccess(NULL)) { ItemWindow (DELETEiw, &IW); return FALSE; } } } break; } /*********************************************************************** * Next attribute (of the same scope). ***********************************************************************/ case NEXTATTRkey_EDIT: for (;;) { attrN = (attrN + 1) % nAttrs; status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_SCOPE_, &scope, NULL_); if (!ReportStatus(status,FALSE)) { ItemWindow (DELETEiw, &IW); return FALSE; } if ((G && scope == GLOBAL_SCOPE) || (!G && scope == VARIABLE_SCOPE)) break; } FreeAttrEntriesMenuX (entryNs, entryTypes, &IW); if (!BuildAttrEntriesMenuX(G,attrN,&nEntries, &entryNs,&entryTypes,&IW)) { ItemWindow (DELETEiw, &IW); return FALSE; } ItemWindow (UPDATEiw, &IW, 0); break; /*********************************************************************** * Display online help. ***********************************************************************/ case HELPkey_FSI: OnlineHelpWindow (ilhFile, BOO(G,GATTRENTRIEShelpIDx, VATTRENTRIEShelpIDx)); break; /*********************************************************************** * Exit menu. ***********************************************************************/ case EXITkey_FSI: ItemWindow (DELETEiw, &IW); FreeAttrEntriesMenuX (entryNs, entryTypes, &IW); return TRUE; } } } /****************************************************************************** * BuildAttrEntriesMenuX. ******************************************************************************/ Logical BuildAttrEntriesMenuX (G, attrN, nEntries, entryNs, entryTypes, IW) Logical G; long attrN; long *nEntries; long **entryNs; int **entryTypes; struct ItemWindowStruct *IW; { CDFstatus status; void *binary; long dataType, numElems, entryN, NgEntries, NrEntries, NzEntries; char field[80+1], attrName[CDF_ATTR_NAME_LEN256+1]; int entryX, curCol, n, dataSpecCol, entryType, itemN; AOSs2 (loadingLines, "Loading menu...", "") /*************************************************************************** * Make attribute current and get name. ***************************************************************************/ status = CDFlib (SELECT_, ATTR_, attrN, GET_, ATTR_NAME_, attrName, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /*************************************************************************** * Determine number of entries. ***************************************************************************/ if (G) { status = CDFlib (GET_, ATTR_NUMgENTRIES_, &NgEntries, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; *nEntries = NgEntries; } else { status = CDFlib (GET_, ATTR_NUMrENTRIES_, &NrEntries, ATTR_NUMzENTRIES_, &NzEntries, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; *nEntries = NrEntries + NzEntries; } if (*nEntries > MANY_ENTRYs) MessageWindow (loadingLines,NULL,LogicalFALSE); *entryNs = (long *) cdf_AllocateMemory ((size_t) ((*nEntries) * sizeof(long)), FatalError); *entryTypes = (int *) cdf_AllocateMemory ((size_t) ((*nEntries) * sizeof(int)), FatalError); if (G) { for (entryN = 0, entryX = 0; entryX < NgEntries; entryN++) { status = CDFlib (SELECT_, gENTRY_, entryN, CONFIRM_, CURgENTRY_EXISTENCE_, NULL_); switch (status) { case NO_SUCH_ENTRY: break; default: if (!ReportStatus(status,FALSE)) return FALSE; (*entryNs)[entryX] = entryN; (*entryTypes)[entryX] = gENTRYt; entryX++; break; } } } else { for (entryN = 0, entryX = 0; entryX < NrEntries; entryN++) { status = CDFlib (SELECT_, rENTRY_, entryN, CONFIRM_, CURrENTRY_EXISTENCE_, NULL_); switch (status) { case NO_SUCH_ENTRY: break; default: if (!ReportStatus(status,FALSE)) return FALSE; (*entryNs)[entryX] = entryN; (*entryTypes)[entryX] = rENTRYt; entryX++; break; } } for (entryN = 0; entryX < *nEntries; entryN++) { status = CDFlib (SELECT_, zENTRY_, entryN, CONFIRM_, CURzENTRY_EXISTENCE_, NULL_); switch (status) { case NO_SUCH_ENTRY: break; default: if (!ReportStatus(status,FALSE)) return FALSE; (*entryNs)[entryX] = entryN; (*entryTypes)[entryX] = zENTRYt; entryX++; break; } } } /*************************************************************************** * Allocate item section control/lines. ***************************************************************************/ AllocIW (IW, (int) (4 * (*nEntries)), (int) *nEntries, 80, FatalError); /*************************************************************************** * Encode label/header. ***************************************************************************/ sprintf (IW->label," %cAttribute \"%s\" Entries ",BOO(G,'g','v'),attrName); if (G) { sprintf (IW->hLines[0], "%ld gEntr%s", NgEntries, BOO(NgEntries == 1,"y","ies")); strcpyX (IW->hLines[1], "Entry DataSpec Value(s)", 0); } else { sprintf (IW->hLines[0], "%ld rEntr%s, %ld zEntr%s", NrEntries, BOO(NrEntries == 1,"y","ies"), NzEntries, BOO(NzEntries == 1,"y","ies")); strcpyX (IW->hLines[1], "VarName DataSpec Value(s)", 0); } /*************************************************************************** * Build each attribute/entry line. ***************************************************************************/ for (entryX = 0, curCol = 0; entryX < *nEntries; entryX++, curCol = 0) { entryType = (*entryTypes)[entryX]; status = CDFlib (SELECT_, ENTRY(entryType), (*entryNs)[entryX], GET_, ENTRY_DATATYPE(entryType), &dataType, ENTRY_NUMELEMS(entryType), &numElems, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; /******************************************************************* * Setup entry number field if global scope, variable name if * variable scope. *******************************************************************/ if (G) { sprintf (field, "%ld", (*entryNs)[entryX] + 1); if (strlen(field) > (size_t) ENTRYNUM_FIELD_LENx) { strcpyX (field + ENTRYNUM_FIELD_LENx - 3, "...", 0); } } else { char varName[CDF_VAR_NAME_LEN256+1]; status = CDFlib (SELECT_, E3(entryType, 0,rVAR_,zVAR_), (*entryNs)[entryX], GET_, E3(entryType,0,rVAR_NAME_,zVAR_NAME_), varName, NULL_); switch (status) { case NO_SUCH_VAR: { Logical Z = E3(entryType,FALSE,FALSE,TRUE); sprintf (field, "<%sEntry.%ld>", BOO(Z,"z","r"), (*entryNs)[entryX] + 1); break; } default: if (!ReportStatus(status,FALSE)) return FALSE; EncodeString (strlen(varName), varName, field, 0, VARNAME_FIELD_LENx); break; } } strcpyX (IW->iLines[entryX], field, 0); if (strlen(field) < (size_t) BOO(G,ENTRYNUM_FIELD_LENx, VARNAME_FIELD_LENx)) { CatNcharacters (IW->iLines[entryX], BOO(G,ENTRYNUM_FIELD_LENx, VARNAME_FIELD_LENx) - strlen(field), (int) ' '); } CatNcharacters (IW->iLines[entryX], BOO(G,ENTRYNUM_FIELD_BLANKSx,VARNAME_FIELD_BLANKSx), (int) ' '); itemN = 4 * entryX; IW->iLineNs[itemN] = entryX; IW->iCols[itemN] = curCol; IW->iLens[itemN] = strlen(field); curCol += BOO(G,ENTRYNUM_FIELD_LENx,VARNAME_FIELD_LENx) + BOO(G,ENTRYNUM_FIELD_BLANKSx,VARNAME_FIELD_BLANKSx); /******************************************************************* * Setup data type & number of elements. *******************************************************************/ strcpyX (field, DataTypeToken(dataType), 0); catchrX (field, (int) '/', 0); sprintf (&field[strlen(field)], "%ld", numElems); if (strlen(field) > (size_t) DATASPEC_FIELD_LENx) { strcpyX (field + DATASPEC_FIELD_LENx - 3, "...", 0); } strcatX (IW->iLines[entryX], field, 0); if (strlen(field) < (size_t) DATASPEC_FIELD_LENx) { CatNcharacters (IW->iLines[entryX], DATASPEC_FIELD_LENx - strlen(field), (int) ' '); } CatNcharacters (IW->iLines[entryX], DATASPEC_FIELD_BLANKSx, (int) ' '); itemN = (4 * entryX) + 1; IW->iLineNs[itemN] = entryX; IW->iCols[itemN] = curCol; IW->iLens[itemN] = strlen(field); dataSpecCol = curCol; curCol += DATASPEC_FIELD_LENx + DATASPEC_FIELD_BLANKSx; /******************************************************************* * Setup value(s) field. *******************************************************************/ binary = cdf_AllocateMemory ((size_t) (numElems * CDFelemSize(dataType)), FatalError); status = CDFlib (GET_, ENTRY_DATA(entryType), binary, NULL_); if (!ReportStatus(status,FALSE)) return FALSE; n = EncodeValuesFormat (dataType, numElems, binary, &(IW->iLines[entryX][curCol]), NULL, 0, BOO(G,gAttrENTRYVALUE_FIELD_LENx, vAttrENTRYVALUE_FIELD_LENx), EPOCH0_STYLE); cdf_FreeMemory (binary, FatalError); /******************************************************************* * Set 'dataSpec/value' item control information. *******************************************************************/ itemN = (4 * entryX) + 2; IW->iLineNs[itemN] = entryX; IW->iCols[itemN] = dataSpecCol; IW->iLens[itemN] = strlen(&(IW->iLines[entryX][dataSpecCol])); /******************************************************************* * Set `value' item control information. *******************************************************************/ itemN = (4 * entryX) + 3; IW->iLineNs[itemN] = entryX; IW->iCols[itemN] = curCol; IW->iLens[itemN] = n; } if (*nEntries > MANY_ENTRYs) MessageWindow (NULL); return TRUE; } /****************************************************************************** * FreeAttrEntriesMenuX. ******************************************************************************/ void FreeAttrEntriesMenuX (entryNs, entryTypes, IW) long *entryNs; int *entryTypes; struct ItemWindowStruct *IW; { FreeIW (IW, FatalError); if (entryTypes != NULL) cdf_FreeMemory (entryTypes, FatalError); if (entryNs != NULL) cdf_FreeMemory (entryNs, FatalError); return; }