/* File: newkey.c * Author: Jean Thierry-Mieg (mieg@mrc-lmb.cam.ac.uk) * Copyright (C) J Thierry-Mieg and R Durbin, 1991 * ------------------------------------------------------------------- * Acedb is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * or see the on-line version at http://www.gnu.org/copyleft/gpl.txt * ------------------------------------------------------------------- * This file is part of the ACEDB genome database package, written by * Richard Durbin (MRC LMB, UK) rd@mrc-lmb.cam.ac.uk, and * Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr * * Description: user interface to edit operations * at level of whole objects: * new object * alias/fuse (separate these ?) * rename * delete * included in graphical ace compilations * Exported functions: * void addKeys (void) * HISTORY: * Last edited: May 6 10:19 2003 (edgrif) * * Dec 1 23:55 1996 (rd) * * Jun 6 18:36 1996 (rd) * * Feb 8 00:04 1992 (rd): added rename, delete and changed alias * * Jan 13 02:31 1992 (mieg): alias. * * Dec 2 19:02 1991 (mieg): graphClassEntry * Created: Mon Dec 2 19:01:40 1991 (mieg) *------------------------------------------------------------------- */ /************************************************************/ #include #include #include #include #include #include #include #include #include #include #include /************************************************************/ static Graph addGraph = 0 ; static int firstClassBox = 0 ; static int currClassBox = 0 ; static int currClass = 0 ; static char nameText[128] ; static Array box2class ; static Array classList = 0 ; static int classListBox = -1 ; static char classNameBuf[32] = {'\0'} ; /************************************************************/ static void findAndDisplayKey (void) ; static void editNewKey (void) ; static void (*preferredAction)(void) = editNewKey ; static void destroy (void); static void pick (int box, double x_unused, double y_unused, int modifier_unused); static void resize (void); static int newKeyClassComplete(char *cp, int len); static void makeAlias (void); static void makeAndDisplayKey (void); static void findAndDisplayKey (void); static void changeName (void); static void deleteObject (void); static void editNewKey (void); static void classSelector (void); static void doAction (char *); static BOOL classListMenuCall (KEY k, int box); static void pickObject (void); static MENUOPT newMenu[] = { { graphDestroy, "Quit"}, { help, "Help"}, { menuSpacer, "" }, { makeAndDisplayKey, "Create"}, { findAndDisplayKey, "Display"}, { editNewKey, "Edit"}, { makeAlias, "Alias-Fuse"}, { changeName, "Rename-Fuse"}, { deleteObject, "Delete"}, { 0, 0 } } ; /******************* main function ****************/ void addKeys (void) { if(!checkWriteAccess()) return ; if (graphActivate (addGraph)) { graphPop () ; resize(); return ; } addGraph = displayCreate("DtAlias") ; graphRegister (DESTROY, destroy) ; graphRegister (PICK, pick) ; graphRegister (RESIZE, resize) ; graphMenu (newMenu) ; *nameText = 0 ; resize(); return; } /* addKeys */ /************************************************************/ static void resize (void) { int graphWidth, graphHeight ; int i, ncol = 3 ; int x, sep = 0 ; float y ; int nclasses = pickVocList[0].key ; int classPickBox ; int firstMenuButton; MENUOPT *buttonItem; if (!graphActivate(addGraph)) return; graphFitBounds (&graphWidth, &graphHeight) ; graphClear(); box2class = arrayReCreate (box2class, 32, int) ; for (i = 1 ; i <= nclasses ; ++i) if (strlen(pickVocList[i].text) > sep) sep = strlen (pickVocList[i].text) ; sep += 2 ; classList = classListCreate (classList, TRUE, TRUE, FALSE, TRUE) ; classPickBox = graphButton ("Class:", classSelector, 16, 2.2) ; graphBoxFreeMenu(classPickBox, (FreeMenuFunction) classListMenuCall, arrp (classList, 0, FREEOPT) ) ; classListBox = graphBoxStart() ; if (graphWidth > 26) graphTextPtr(classNameBuf, 24, 2.35, graphWidth - 25) ; graphBoxEnd() ; graphBoxDraw(classListBox,BLACK,CYAN) ; graphButton ("Pick object", pickObject, 2.0, 2.2) ; firstMenuButton = graphButtons (newMenu, 2, 4.5, graphWidth) ; x = 0 ; /* find out how many rows graphButtons has drawn - very hacky ! */ i = 0; buttonItem = &newMenu[0]; while (buttonItem->text) { if (strlen(buttonItem->text) > 0 && buttonItem->f) i++; buttonItem++; } graphBoxDim(firstMenuButton + i-1, 0, 0, 0, &y); y += .5; firstClassBox = 0; for (i = 1 ; i <= nclasses ; ++i) { KEY class1 = pickVocList[i].key ; unsigned char dummy ; int box; pickIsA(&class1, &dummy) ; if (pickList[class1 & 255].type != 'B') continue ; if (pickList[class1].protected) continue ; box = graphBoxStart(); if (!firstClassBox) firstClassBox = box; array (box2class,box,int) = pickVocList[i].key ; graphText (name(pickVocList[i].key), 2.0 + (float)(x*sep), y) ; graphBoxEnd () ; if (!(++x%ncol)) { x = 0 ; y += 1 ; } } graphText ("Name: ", 2.0, 0.5) ; graphCompletionEntry (newKeyClassComplete, nameText, 127, 9.0, 0.5, doAction) ; currClass = currClassBox = 0 ; graphFitBounds (&graphWidth, &graphHeight) ; graphButtons (newMenu, 2, y + 2, graphWidth) ; graphRedraw () ; return; } /* resize */ static void doAction (char *dummy_entry) { (*preferredAction)() ; } static BOOL checkName (void) { char *cp; if (!checkWriteAccess ()) /* may be lost after graph was created */ return FALSE ; if (!currClass) { messout ("Please, first pick a class") ; return FALSE ; } if (!*nameText) { ACEIN name_in; name_in = messPrompt ("Please enter the name of " "the object to be edited", "","w", 0); if (!name_in) return FALSE ; aceInNext (name_in) ; strncpy (nameText, aceInPos(name_in), 127) ; nameText[127] = 0; aceInDestroy (name_in); } if (!*nameText) { messout ("The name can not be empty") ; return FALSE ; } cp = nameText ; cp-- ; while (*cp++) if (*cp == '*' || *cp == '?') { messout("Please do not use * or ? in a new name") ; return FALSE ; } return TRUE ; } /******************* action functions ******************/ static KEY makeKey (void) { KEY key ; if (!checkName()) return 0 ; if (!lexaddkey (nameText, &key, currClass)) messout ("%s %s already exists.", name(currClass), name(key)) ; return key ; } static void displayKey (key) { if (pickType(key) == 'B') { OBJ obj = bsUpdate(key) ; /* to give it a cache entry */ bsDestroy (obj) ; display (key, 0, "TREE") ; } else display (key, 0, 0) ; /* A type cannot be shown as TREE */ } /****************/ static void findAndDisplayKey (void) { KEY key ; preferredAction = findAndDisplayKey ; if (!checkName()) return ; if (!lexword2key (nameText, &key, currClass) && !(messQuery (messprintf ("%s : %s does not yet exist\n" "Do you want to Create it ?", name (currClass), nameText)) && (key = makeKey()))) return ; displayKey (key) ; } static void makeAndDisplayKey (void) { KEY key = makeKey () ; preferredAction = makeAndDisplayKey ; if (key) displayKey (key) ; } static void editNewKey (void) { static Graph treeGraph = 0 ; KEY key ; OBJ obj ; KEY class = currClass; unsigned char dummy; preferredAction = editNewKey ; if (!checkName()) return ; if (!lexword2key (nameText, &key, currClass)) { if (!messQuery (messprintf ("%s : %s does not exist, do you want to create it ?", name (currClass), nameText))) return ; else lexaddkey (nameText, &key, currClass) ; } pickIsA(&class, &dummy); if (pickType(KEYMAKE(class, 0)) != 'B') { makeKey () ; messout ("Only Tree objects can be edited here, sorry") ; return ; } obj = bsUpdate(key) ; if (graphActivate (treeGraph)) treeDisplay (key, 0, TRUE, NULL) ; else { display (key, 0, "TREE") ; treeGraph = graphActive() ; } bsDestroy(obj) ; /* All this is to see empty objects */ treeUpdate () ; } static void makeAlias (void) { KEY key ; char *aliasName ; int classe = currClass ; ACEIN name_in; preferredAction = makeAlias ; if (!checkName()) return ; if (!lexword2key (nameText, &key, classe)) { messout ("Old name %s is unknown", nameText) ; return ; } name_in = messPrompt ("Alias will result in both the old and new names being " "recognized, but the name you type now will be the " "one the database writes out (canonical name). If it is " "the name of an existing object then the two will be fused. " "Cancel and start again if you wish the name you " "originally typed to be the canonical name." "\n" "\n" "Give alias name:", nameText, "t", 0); if (!name_in) return ; aliasName = aceInWord (name_in); if (strlen(aliasName) == 0) { messout ("The name can not be empty") ; aceInDestroy (name_in); return ; } if (lexAlias (key, aliasName, TRUE, TRUE)) display (key, 0, "TREE") ; else messout ("Alias failed, sorry") ; aceInDestroy (name_in); return; } /* makeAlias */ static void changeName (void) { KEY key ; char *newName ; int classe = currClass ; ACEIN name_in; preferredAction = changeName ; if (!checkName()) return ; if (!lexword2key (nameText, &key, classe)) { messout ("Old name %s is unknown", nameText) ; return ; } name_in = messPrompt ("Rename is a hard rename function. Unless you are just " "changing case, the old name will no " "longer apply to this or any other current object (you can " "reuse it for a new object). If the new name belongs to " "an existing object the two objects will be fused. " "For both names to apply, cancel " "now and use the Alias menu entry. " "\n" "\n" "Give new name:", nameText, "t", 0); if (!name_in) return ; newName = aceInWord (name_in) ; if (strlen(newName) == 0) { messout ("The name cannot be empty") ; aceInDestroy (name_in); return ; } if (!lexAlias (key, newName, TRUE, FALSE)) messout ("Rename failed, sorry") ; aceInDestroy (name_in); return; } /* changeName */ /************************* delete functions **********************/ static void deleteKey (KEY key) { OBJ obj ; switch (pickType (key)) { case 'A': arrayKill (key) ; /* neat, heh! */ break ; case 'B': if ((obj = bsUpdate (key))) bsKill (obj) ; else messout ("Object %s is locked", name (key)) ; break ; } } static void deleteObject (void) { KEY key ; int classe = currClass ; preferredAction = deleteObject ; if (!checkName()) return ; if (!lexword2key (nameText, &key, classe)) messout ("Object %s is unknown", nameText) ; else if (messQuery (messprintf ("Delete all data associated %s ?", name(key)))) deleteKey (key) ; return; } /* deleteObject */ /****************************************/ static BOOL classListMenuCall (KEY k, int box) { /* if (currClassBox) graphBoxDraw (currClassBox, BLACK, WHITE) ; currClassBox = box ; */ currClass = k ; strncpy(classNameBuf,name(currClass),31) ; classNameBuf[31] = '\0' ; graphBoxDraw(classListBox,BLACK,CYAN) ; return TRUE ; } /* classListMenuCall */ static void classSelector (void) { KEY key ; if (graphSelect (&key, arrp (classList, 0, FREEOPT))) classListMenuCall (key, 0) ; graphBoxDraw(classListBox,BLACK,CYAN) ; return; } /* classSelector */ static void pick (int box, double x_unused, double y_unused, int modifier_unused) { if (!box) return ; if (box >= firstClassBox && box < arrayMax(box2class)) { if (currClassBox) graphBoxDraw (currClassBox, BLACK, WHITE) ; currClassBox = box ; graphBoxDraw (currClassBox, WHITE, BLACK) ; currClass = arr(box2class,currClassBox,int) ; strncpy(classNameBuf,name(currClass),31) ; classNameBuf[31] = '\0' ; graphBoxDraw(classListBox,BLACK,CYAN) ; } } /******************* pick Object button *************/ static void blockPickObject (KEY key) { int i ; KEY classKey ; unsigned char mask ; if (currClassBox) graphBoxDraw (currClassBox, BLACK, WHITE) ; currClassBox = 0 ; currClass = class(key) ; for (i = 0 ; i < arrayMax(box2class) ; ++i) { classKey = arr(box2class, i, int) ; pickIsA (&classKey, &mask) ; if (!mask && classKey == currClass) { currClassBox = i ; graphBoxDraw (i, WHITE, BLACK) ; } } strncpy(classNameBuf,className(key),31) ; classNameBuf[31] = '\0' ; graphBoxDraw(classListBox,BLACK,CYAN) ; strncpy (nameText, name(key), 127) ; nameText[127] = 0 ; graphCompletionEntry (0, nameText, 0, 0, 0, 0) ; } static void pickObject (void) { displayBlock (blockPickObject, 0) ; } /****************************************************/ static void destroy (void) { addGraph = 0 ; currClassBox = 0 ; } /*******************************************************/ static int newKeyClassComplete(char *cp, int len) { if (currClass) return ksetClassComplete (cp, len , currClass) ; else return 0 ; } /************************** eof *****************************/